Upgrading from 0.1.0-rc.2 to 0.2.0-rc? Read
MIGRATION.md first — it lists the four
behaviour changes and the concrete recovery flags. Then run
xtr-on-rust doctor against your xtr.yaml to catch
placeholder credentials, weak URL-guard postures, or
security-server misconfig before you deploy.
Please do not open a public GitHub issue for security-sensitive findings. Instead:
- Preferred: use GitHub's private vulnerability reporting for this repo — Security tab → Report a vulnerability. That routes the report to maintainers via a private thread with tracking.
- Fallback: email
rainer.turner@gmail.comwith[XTR-security]in the subject line.
Include, when you can:
- Affected version (image tag or git ref)
- Reproduction steps or PoC
- Impact assessment (what an attacker gains)
- Any suggested mitigation
- Acknowledgement: within 3 business days of the report reaching a maintainer.
- Triage decision (accepted / needs-more-info / not-a-vuln): within 7 business days.
- Fix + coordinated disclosure: target 30 days for CRITICAL and HIGH severity, 90 days for MEDIUM. Extension is negotiable if a fix requires a coordinated upstream change.
- Credit: reporters are credited in the release notes unless they ask to remain anonymous.
Only the latest published release receives security fixes. XTR-on-Rust is pre-1.0 and follows SemVer — minor bumps are the norm, patch releases are cut only for critical fixes on the current line.
| Version | Support status |
|---|---|
0.1.x |
✅ Supported (current scaffold; no domain yet) |
< 0.1.0 |
n/a |
Every rule below is documented in STANDARDS.md.
cargo audit --deny warnings— every push, every PR, daily at 06:00 UTC. Advisory exceptions live in.cargo/audit.tomlwith a rationale and a review date; blind ignores are a code smell.cargo deny check all— enforces license allow-list (Apache-2.0 compatible only, no GPL/AGPL/SSPL), refuses git-URL deps and wildcard version specs, warns on duplicate crate versions. Config:deny.toml.- Trivy image scan on every release-tag publish, gated on
HIGHandCRITICALfixed vulnerabilities. Blocks signing. - cosign keyless signatures on every published image digest
via Sigstore OIDC. Verify recipe in
book/src/ops/docker.md. - In-toto provenance + SPDX SBOM attached to every multi-arch manifest.
- Reproducible image layer timestamps (
SOURCE_DATE_EPOCH+rewrite-timestamp=true) so the same commit produces the same image digest. Rust binary bit-for-bit determinism is NOT yet enforced. - Multi-arch smoke test — every release image is booted under
QEMU on both
linux/amd64andlinux/arm64and probed with/healthbefore it's signed. A signed image is a working image. - Non-root container user (uid 1000), read-only rootfs,
cap_drop: ALL,no-new-privileges: truein the shippeddocker-compose.yml.
Domain-specific scope will be documented once XTR's semantics are defined. As a general rule, the operator is responsible for:
- Secret fetching (Vault / KMS / Docker secrets)
- Persistent state / cross-replica coordination
- Rate limiting (terminate at a reverse proxy)
- IAM / JWT validation at the boundary
The audit-v1 C1 URL guard rejects literal-IP
metadata endpoints (169.254.169.254, RFC-1918 ranges, IPv6
link-local, IPv4-mapped-IPv6, etc.) at WSDL ingest time. It
does not resolve hostnames — a WSDL that names
metadata.attacker.example and DNS-resolves it to
169.254.169.254 at request time will pass the guard, and
reqwest will then connect. This is deliberate: DNS at boot
gives a stale-cache false confidence, and per-request DNS
enforcement raises latency for every call.
Close the hostname-DNS lane with one of these two operator recipes (pick either; both together for high-value deployments):
-
Host allowlist in
xtr.yaml— pin the set of upstreams:wsdl: upstream_host_allowlist: - ariregxmlv6.rik.ee - jvis.envir.ee
Any WSDL or sidecar that names a host outside this set fails at boot; DNS trickery becomes irrelevant because unknown hostnames never reach the resolver.
-
Container egress network policy — deny outbound to metadata/loopback/private ranges at the network layer. Example for the shipped
docker-compose.yml:# docker-compose.override.yml services: xtr: # Deny the AWS/GCP metadata IP outright. # Add equivalent rules for Azure (169.254.169.254 too), # AliCloud (100.100.100.200), and your VPC-private ranges. cap_add: - NET_ADMIN command: - sh - -c - | iptables -A OUTPUT -d 169.254.169.254 -j REJECT && iptables -A OUTPUT -d 100.100.100.200 -j REJECT && exec /usr/bin/tini -- /app/xtr-on-rust
Or, at the Kubernetes layer, a
NetworkPolicyegress rule withipBlock.exceptcovering all the metadata IPs.
If neither is applied, treat the WSDL mount as a trust boundary equivalent to code review: only load WSDLs from sources you would accept commits from.