Repository navigation
security(admission): enforce credential-file access boundary #246
Description
Valid finding
Fresh inspection of Agent Artifact Admission exact head 63231dcf493ff3e5f53630ffd04016299358021d found that crates/agent-artifact-admission/src/config.rs::load_admin_token() validates bounded JSON and token contents but read_bounded() opens the credential path without enforcing host filesystem access permissions. The shipped runbook simultaneously requires the administrator-token credential file to have restrictive filesystem permissions and calls it a protected local secret.
This leaves a gap between documented deployment policy and executable startup acceptance. On a shared Unix host, a group/world-readable credential file can expose the bearer token to an unintended local principal, and a group/world-writable credential file can permit unauthorized replacement of security-relevant authentication material. Because the admission service is loopback-only, same-host credential exposure is directly relevant: possession of the token authorizes /v1/policy and /v1/admissions.
MITRE CWE-732 (Version 4.20) explicitly treats overly broad access to security-critical configuration/credential resources as a confidentiality/integrity weakness and recommends checking insecure permissions and failing startup rather than relying on operators to tighten them manually: https://cwe.mitre.org/data/definitions/732.html
NIST SP 800-53 Rev. 5, AC-6/AC-6(1), requires least privilege and explicit authorization to security functions and security-relevant information; NIST's current publication page records Release 5.2.0 as the latest minor release: https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final
Ownership boundary
This is Wardnet-local credential admission for the standalone Agent Artifact Admission process. It does not create a secret-management backend, duplicate Keyverse, implement quarantine/runtime isolation, alter EgressWeave transport authority, or change contextual-orchestrator/AppGuardrail ownership. Long-lived enterprise secret distribution remains an external/canonical secret-management concern; Wardnet must still fail closed when it is explicitly given a local credential file whose access boundary contradicts its own deployment contract.
RED acceptance
Do not mutate #129 while its current uv hash-mode test-only head is awaiting exact hosted execution. After that lineage settles, create a fresh test-first successor and require on Unix:
- an otherwise valid credential file with any group/other read, write, or execute permission is rejected before listener bind;
- owner-only
0600and read-only0400credential files remain valid positive controls; - the error is the existing non-secret
ConfigError::InvalidCredential(or an equally bounded typed credential-access error) and does not expose the token or path contents; - the test proves the failure through
load_admin_tokenand the CLI/startup boundary, not by source-string inspection.
Windows ACL semantics are not to be approximated with POSIX mode bits. If the supported Windows deployment cannot obtain an equivalent trustworthy ACL predicate through the standard/runtime platform APIs, keep that platform fail-closed for this local-file credential mode until a separately evidenced ACL adapter exists; do not silently claim parity.
Symlink/TOCTOU ownership is a separate finding unless a concrete exploit/reproduction proves it should be solved in the same causal slice.
Minimum repair boundary
Only after a semantic RED: validate permissions from the already opened credential file's metadata so the decision is bound to the handle actually read; on Unix reject group/other permission bits before parsing/returning token material. Keep config-policy/audit-path permissions out of this slice unless their own hostile tests demonstrate a distinct requirement. Update the runbook/CHANGELOG and trace CWE-732 + NIST AC-6 to executable evidence.
Completion gate
Close only when an exact unchanged candidate has hostile RED lineage, minimum causal source repair, cargo fmt --check, locked workspace tests, strict Clippy, then-live security/review/coverage/SBOM/provenance gates, fresh protected-base compatibility, and reaches protected main or a verified successor carries every valid delta. No self/model approval, routine administrator bypass, force update, gate weakening, or predecessor-evidence transfer.
Activity
seonghobae commentedon Sep 10, 2026
Completion receipt: PR #247 exact
2efe188cd94b77d039c749368cfeee977dbb51e4carried the complete #246 credential-file access contract. Hosted semantic REDd9126dba9fad4332eec16cb441d3fb7a569452b4proved0640credential material was accepted after the preceding suite passed. The minimum repair opens the credential path once, validates metadata on that same handle before materializing secret bytes, rejects any Unix group/other permission bit (mode & 0o077 != 0) through the existing non-secretInvalidCredentialoutcome, preserves owner-only0600/0400, and fails the local-file boundary closed where equivalent POSIX permission semantics are unavailable. Exact CI34436046500and Fuzz34436046509are terminal SUCCESS and PR #247 has zero review threads. #247 was ordinarily merged into canonical #129 as473f689fa6fd0c9662e4709e5d6257715371bf36; fresh ancestry comparison proves that merge is an ancestor of current #129c4030f7fecaa5627ccec31ce58eca7e59db45334(ahead 17 / behind 0). The full implementation/test/evidence delta is therefore retained by the canonical successor lineage; no force update, gate weakening, protected-main or release claim.