chore(restack): adopt protected auth baseline into runtime configuration - #310
Conversation
* fix(auth): fail closed without write-capable admin on public bind * fix(auth): reject unusable bootstrap credentials * fix(auth): reject header-ambiguous admin secrets * docs(security): record research redistribution assessment * test(auth): strengthen strict admin-token properties * test(auth): mirror strict admin-token rejection in fuzz target * test(auth): keep fuzz role semantics in sync * test(auth): property-check credential and RBAC boundary * test(auth): exercise fuzz invariants for arbitrary bytes * fix(auth): align health and write denial auth semantics * test(auth): reject fixed smoke administrator credential * fix(auth): mint ephemeral smoke administrator credential * docs(security): preserve fail-closed auth traceability * test(auth): bind smoke token generation to forwarding * docs(auth): retain redistributable NIST SSDF evidence * docs(auth): preserve external-secret deployment lifecycle after restack * docs(security): reconcile NIST artifact provenance --------- Co-authored-by: OpenAI Codex <codex@openai.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Fresh exact-head repair finding: the ordinary expected-head merge of The conflict sits on the bootstrap/auth edge. Protected #155 changed both
No ours/theirs shortcut, force update, destructive rebase, gate weakening, or closure by replacement. GREEN requires a non-force two-parent adoption of the exact protected and feature heads, followed by fresh exact-head CI/Fuzz/Security/SAST/CodeQL/review/thread evidence; predecessor receipts are historical after the merge. |
|
Fresh semantic conflict inventory against unchanged protected Conflict resolution must synthesize, not choose ours/theirs:
Acceptance on the resulting non-force two-parent/current-base head: the #140 runtime architecture-fitness suite plus all #155 credential/RBAC/public-bind hostile tests must pass together; no direct operational env reads outside the designated runtime/credential bootstrap adapters; exact-current CI/security/coverage/CodeQL/review/thread evidence must be reacquired. Do not move dependents until this root is semantically GREEN. |
|
Fresh repair evidence on current Runtime Configuration head Current combined commit statuses on |
|
Fresh exact-source synthesis for the remaining The minimum causal merge is not an ours/theirs file choice. Keep protected #155's
pub async fn run_from_env(
shutdown: std::pin::Pin<Box<dyn std::future::Future<Output = ()> + Send>>,
) -> Result<(), Box<dyn std::error::Error>> {
let runtime = RuntimeConfiguration::from_env()?;
let listen_loopback = listen_is_loopback_only(&runtime.bind_addr);
let (credentials, _) = CredentialRegistry::bootstrap_from_env()?;
let config = runtime.app_config(&credentials);
let admin_tokens = match credentials.get_credential(CRED_ADMIN_TOKENS) {
Some(raw) if !raw.trim().is_empty() => parse_admin_tokens_strict(raw)?,
_ => HashMap::new(),
};
let has_write_capable_admin = if !admin_tokens.is_empty() {
admin_tokens.iter().any(|(token, principal)| {
principal.can_write && admin_secret_supports_header_auth(token)
})
} else {
credentials
.get_credential(CRED_ADMIN_TOKEN)
.is_some_and(admin_secret_supports_header_auth)
};
require_write_auth_for_bind(&runtime.bind_addr, has_write_capable_admin)?;
let listener = tokio::net::TcpListener::bind(&runtime.bind_addr).await?;
let local_addr = listener.local_addr()?;
let auth_mode = if listen_loopback && !has_write_capable_admin {
"development"
} else {
"production"
};
let state = AppState::load(config)
.await
.map_err(|message| std::io::Error::new(std::io::ErrorKind::InvalidData, message))?
.with_rate_limit(runtime.rate_limit, runtime.rate_limit_window)
.with_admin_tokens(admin_tokens)
.with_credentials_source(credentials.source())
.with_listen_loopback(listen_loopback)
.with_max_body_size(runtime.max_body_bytes);
println!("waf-ids-ai-soc listening on http://{local_addr} auth_mode={auth_mode}");
std::io::Write::flush(&mut std::io::stdout())?;
let served = axum::serve(listener, build_app(state))
.with_graceful_shutdown(shutdown)
.await;
served?;
Ok(())
}This preserves the already-reconciled credential adapter as secret authority and makes the immutable Hostile GREEN on the resulting unchanged exact head must include both lineages together: #140 recursive env-authority fitness + zero-bound/runtime snapshot tests, and #155 non-loopback/no-admin, unpresentable token, readonly-only principal, strict duplicate/blank/unknown-role parsing, health |
|
Fresh protected-base repair update: root #140 advanced non-force to exact |
|
A serialized child now carries the hostile RED prerequisite for this synthesis: Draft #430, base |
|
Fresh synthesis-status correction, 2026-09-17 KST: the PR body’s #430 helper-only status is superseded. Serialized child #430 is now exact |
973223f
into
feat/runtime-config-bootstrap-snapshot
Foundation-first, non-force synthesis only. Runtime Configuration owner #140 remains exact
7d98725cc51b259b0be940385b2245758d098081; protected/defaultmainremainsf8260f1e03836039ff9463dd99fa982e4e270c4bafter #155. This reverse-direction lane exists only to adopt protected authentication/security truth into the moving #140 foundation before any trusted-proxy or PostgreSQL dependent moves.Current conflict / serialized synthesis — 2026-09-17 KST
GitHub still reports this Draft PR mechanically non-mergeable because its head is protected
mainand its base is the pre-#155 #140 lineage. Its recorded base SHA is historical because #140 moved after #310 opened; that movement is an intervening delta to adopt normally, not a reason to force/rebase or discard either side.src/credentials.rson #140 is already causally reconciled with #155: strict credential-file JSON typing, blank/null rejection, visible-ASCII/header-safe secret admission, constant-time comparison, loopback/public-bind helpers and hostile tests are preserved whileCredentialRegistry::bootstrap_from_envremains the process-edge secret adapter. Blank/whitespaceWAF_IDS_CREDENTIALS_PATHremains unset. Blank/whitespaceWAF_IDS_STATE_PATHalso remains in-memory/unset through the hostile regression.The former semantic source conflict was
src/lib.rs. The architecture text on #140 states the actualCredentialRegistry+ write-capable, header-presentable administrator contract and rejects TLS/identity controls or read-only credentials as substitutes for the public-bind write-auth prerequisite.The #140 architecture-fitness hardening remains current.
6b314dd3b0541328726ffacb097fec1c6054efdbreplaced substring matching with token-structured Rust syntax analysis so function-item aliases and import aliases cannot hide direct process-environment authority while comments and normal/raw strings do not cause false positives.c039776bb15a3af936cd93720c60c27f777dd4aafixed the hostile lifetime-apostrophe edge. Current exact parent7d98725...additionally contains the format-only repair exposed by child CI before any semantic authentication test ran.Serialized Draft child #430 is the active synthesis/admission lane on exact #140 and has advanced to exact
65b887e347d47e3cd29071342c353408c3f14e4a. The hostile RED remains causal history: test-only exact062ea6ab787d0a1d864e429a95f7ed1642fbf37eproduced Fuzz35029440921SUCCESS and CI35029440905/ rust job104584220679, which proved stalerun_from_envcould bind public0.0.0.0:44429without a write-capable administrator and left protected-auth helpers unused.The invalid attempted repair
408e8b8de90d061e6ef01414f298f2156d2466dfreplaced nearly all ofsrc/lib.rs(221additions /6777deletions) and violated the bounded synthesis requirement;61790e2a46e8c45467f57558673e5a1b8a2e0490immediately reverted it. No result from that source is promotable.The deterministic one-shot synthesis subsequently executed successfully on exact helper input
cc8f721775e808ff00961dc8e29540e34720b1c2. Run35160876925, job105011075007, pinned checkout by immutable SHA, guarded the expected predecessor and protectedmain@f826..., reconstructed from the complete protectedsrc/lib.rs, applied only the reviewed Runtime Configuration/authentication composition, passedcargo fmt,git diff --check,cargo test --locked --test runtime_configuration_auth_synthesis, andcargo test --locked --lib, then committed onlysrc/lib.rsas0e0f01efbd6e21874c94eed987192534e234f211. The temporary helper workflow was removed by ordinary fast-forward follow-up at current exact65b887e...and is no longer part of the child diff.The synthesized child now preserves protected #155 source/tests and #140's bounded Runtime Configuration delta in one complete source tree.
run_from_envconsumes one immutableRuntimeConfiguration; secrets remain underCredentialRegistry::bootstrap_from_env; strictADMIN_TOKEN/ADMIN_TOKENS, header-presentable write-capable-principal derivation, constant-time request authentication, listener loopback state,require_write_auth_for_bindbefore public listener bind, readinessauth_mode,with_listen_loopback, management 401/403, request-body/rate-limit, state/credential/flush/shutdown invariants and single-sourced parse helpers are retained. No source truncation, second configuration/credential authority, foreign-owner implementation, mutable dependency, source copy or cross-service SQL was introduced.Exact-current admission state
Construction GREEN does not substitute for unchanged-current-head admission. Current #430 exact CI
35180770661/ rust job105072217366and Fuzz35180770659/ fuzz job105072216969remain QUEUED at the latest fresh read. Do not blind-rerun, add no-op source churn, merge the child, move #140, or restack #193 and later dependents while that exact head is still non-terminal.Once #430 has repository-native hostile/authentication GREEN plus then-current security/review/thread/base evidence on the unchanged exact head, merge it normally into #140. Then reconcile #140 non-force against protected main, preserving the complete current #140 architecture/configuration delta and protected authentication truth. Only after that settled root exists should PostgreSQL/trusted-proxy dependents move in dependency order.
Remaining repair acceptance
The eventual #140 integration must simultaneously:
7d98725cc51b259b0be940385b2245758d098081, including the token-structured environment scanner, lifetime hostile regression, current formatter truth and corrected architecture authority text;RuntimeConfigurationdelivery snapshot and forbid direct non-secret environment authority outside designated bootstrap adapters;CredentialRegistry::bootstrap_from_envboundary;WAF_IDS_STATE_PATHandWAF_IDS_CREDENTIALS_PATHsemantics;runtime_config.rsrather than duplicating them inlib.rs;docs/architecture.mdauthority contract already repaired on refactor(config): centralize runtime bootstrap snapshot #140;No force update, destructive rebase, source truncation, wholesale ours/theirs selection, gate weakening, predecessor-result promotion, routine bypass, mutable foreign dependency, source copy, cross-service SQL or dependent feature delta.