mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 14:11:31 +00:00
harden(auth): LOW + Nit batch — bootstrap audit, crypto/rand, XFF trust, CSRF check, protocol-prefix unify (Batch 1)
Audit 2026-05-10 — close 8 LOWs + 2 Nits in-bundle. Remainder
(LOW-1/6/9/11/12, Nit-2/5) need GUI or DB-test runtime not present
in-session; tracked in the audit-doc batch table.
LOW-2: bootstrap.ValidateAndMint now emits 'bootstrap.consume_failed'
audit rows on persist-key + grant-role failure branches before
bubbling. Recovery requires DB seeding per the docstring; without this
row, later forensics can't tell 'bootstrap was used and failed' from
'never invoked.'
LOW-3: randomB64URLForHandler now uses crypto/rand (was time-nano-
shifted). Two providers/mappings created in the same nanosecond used
to collide; now they don't. Time-nano fallback retained for the
unlikely crypto/rand-broken path.
LOW-4: breakglass.verifyDummy uses s.readRand(salt) for the dummy
Argon2id verify. Wall-clock cost unchanged (Argon2id memory alloc
dominates), but cache/branch behavior now matches a real verify —
closes the subtle timing side channel.
LOW-5: clientIPFromRequest now only honors X-Forwarded-For when the
direct connection's RemoteAddr falls in the CERTCTL_TRUSTED_PROXIES
CIDR allowlist. Default-deny: empty list means XFF is ignored.
SetTrustedProxies wired in cmd/server/main.go from cfg.Auth.TrustedProxies.
LOW-7: internal/auth/protocol_endpoints.go::ProtocolEndpointPrefixes
now carries /scep-mtls + /.well-known/est-mtls (previously only in
router.AuthExemptDispatchPrefixes; the two lists had drifted). The
canonical-prefix coverage test in Phase 12 still pins the set.
LOW-8: docs/operator/rbac.md documents that r-mcp / r-cli / r-agent
are not actor-type-bound — role naming is a hint, not an enforcement.
Operators wanting hard binding must apply periodic audit queries.
Native binding is on the v2 roadmap.
LOW-10: Session.Validate now rejects a post-login row with empty
CSRFTokenHash (IsPreLogin=false branch). validSession test fixture
updated with a valid 64-hex CSRF hash.
Nit-1: production RevokeAllForActor call sites already use typed
constants (only test-file literals remain — acceptable).
Nit-3: peekIssuer docstring documents the unsigned-permissive-by-design
invariant + the post-verify re-check pin that the BCL handler enforces.
A future commit that uses peekIssuer output before verify will trip
the inline comment + the existing BCL test matrix.
Status table updated in cowork/auth-bundles-audit-2026-05-10.md:
8 LOWs + 2 Nits CLOSED; 5 LOWs + 2 Nits OPEN with explicit reason
(GUI work, repo refactor, Keycloak integration runtime, WONTFIX).
Refs: cowork/auth-bundles-audit-2026-05-10.md LOW-2/3/4/5/7/8/10
cowork/auth-bundles-audit-2026-05-10.md Nit-1/3
This commit is contained in:
@@ -1597,6 +1597,17 @@ type AuthConfig struct {
|
||||
// legacy `api-key` auth type ignore this struct entirely.
|
||||
Session SessionConfig
|
||||
|
||||
// TrustedProxies is the comma-separated list of CIDR ranges from
|
||||
// which X-Forwarded-For is honored. Empty (default) disables XFF
|
||||
// trust entirely — every request's source IP is read from
|
||||
// r.RemoteAddr regardless of XFF headers. Audit 2026-05-10 LOW-5
|
||||
// closure: pre-fix the audit subsystem trusted any caller-supplied
|
||||
// XFF for IP attribution, letting an attacker inject arbitrary IPs
|
||||
// into audit rows + session IP-binding. Post-fix XFF is read only
|
||||
// when the direct connection's RemoteAddr is in this allowlist.
|
||||
// Setting: CERTCTL_TRUSTED_PROXIES (e.g. "10.0.0.0/8,192.168.0.0/16").
|
||||
TrustedProxies []string
|
||||
|
||||
// DemoModeAck must be true to allow CERTCTL_AUTH_TYPE=none with a
|
||||
// non-loopback listen address. Default false. Audit 2026-05-10
|
||||
// HIGH-12 closure: pre-fix, an operator who flipped Type=none
|
||||
@@ -1869,6 +1880,8 @@ func Load() (*Config, error) {
|
||||
// Audit 2026-05-10 HIGH-12 closure: required-true to allow
|
||||
// CERTCTL_AUTH_TYPE=none with a non-loopback listen address.
|
||||
DemoModeAck: getEnvBool("CERTCTL_DEMO_MODE_ACK", false),
|
||||
// LOW-5: XFF trust allowlist (CIDRs). Empty = ignore XFF.
|
||||
TrustedProxies: getEnvList("CERTCTL_TRUSTED_PROXIES", nil),
|
||||
// NamedKeys is populated from CERTCTL_API_KEYS_NAMED below so Load()
|
||||
// can surface parse errors alongside other config errors.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user