Repository navigation
Conversation
ADR-0050 decides the header-borne, service-level sibling of ADR-0042's query bearer claim: the opt-in shape, exclusive admission, what the host verifier is given, the verdict's own authentication scheme, which operations admit it, and the threat model. Refs #1586.
The acceptance cases of ADR-0050, written against the API the record decides and nothing that exists yet: the floor's admission and exclusivity rules, the verifier's answers, the compile-fail probes in the stub module, the assembled-service wiring with a spy verifier, the secrecy search, the unsigned-payload differential, the RustFS admin dialect census and the recorded-corpus redaction. Nothing here compiles or passes until the implementation lands. Refs #1586.
Written while implementing ADR-0050, still ahead of the code they hold: - the claim names an x- extension header only, and the STS service refuses the scheme although its endpoint admits an anonymous form; - an unrouted object form beside the token is neither read nor verified; - the claim is applied at build whatever the order of the builder calls; - the withheld header is outside the accepted head, and classify agrees; - the privileged probe is request_context_runtime's, not a second one. Three fixtures of the first test commit did not compile for their own reasons (a missing Clone and two borrowed temporaries); they are corrected here. The two consolidation guards list the new modules. Refs #1586.
A host whose outer layer has already authenticated a non-AWS token installs one claim (an x- header name) and one verifier with ServiceBuilder::host_verified_header_token. A request whose only credential is that header is admitted by the security floor as far as the verifier, which reports the identity the host established, and the verdict the gateway mints carries that principal under its own scheme, AuthSchemeRef::HeaderToken. Without the opt-in nothing reads the header. - sig: HeaderTokenClaim, the sealed HeaderTokenAdmission and HeaderTokenReceipt, the HeaderTokenVerifier trust boundary, Admission::HeaderToken and Verdict::HeaderToken. The claim's branch runs first in SecurityFloor::admit and is total: the header beside any other credential surface, a repeated or misshapen value, and a privileged, STS, bearer-claimed or SigV4-only operation are refused AccessDenied before any verifier is asked. - core: RequestContextView::header_token_principal. - gateway: the verifier runs behind the panic boundary; a refusal, a panic and a missing verifier are 403 and never anonymous; the claimed header is removed before acceptance, so no context holds the token; the body is held to what an anonymous body is; an unrouted form beside the token is not read; a HEADER_TOKEN_POSTURE start-up line. - corpus: x-auth-token and x-storage-token are credential headers. BREAKING: AuthSchemeRef gains HeaderToken; sig 0.15.0, core 0.60.0, gateway 0.62.0. The verdict's unit tests move to verdict_tests.rs at the 800-line limit, and the bearer arm moves to service/host_tokens.rs with its behaviour unchanged. Fixes #1586.
From an independent security read of the implementation and from the first mutation run: - the compile-fail probe for a token accessor also failed on a lifetime, so it could not go red; it and the two Clone probes now fail for one reason each, and every probe names the code it was measured to give; - an operation that takes a browser form refuses the scheme in the floor's own predicate, so the posture line no longer lists PostObject; - a verifier panic whose payload panics again when released is contained and still answered 403, for the bearer verifier too; - the classify case for an unrouted form sent no Host and so compared nothing; it now holds classify to the head-only refusal; - the verifier's contract, the builder and ADR-0050 state the host's duties the gateway cannot see: an alias header, an identity the policy source can tell from an access key, a shared cache, the acceptance limits the withheld header is outside of, and that one claim is in force. Refs #1586.
DO NOT MERGE. Twenty mutations of #1590, applied together so that one CI run records which of its assertions go red on the pull-request gate. The branch is deleted once that run has been read.
Collaborator
Author
|
Read: run 42994082473 went red in the three jobs and on the twenty-one assertions the description lists, and nowhere else that is evidence. Closing; the branch is deleted. |
This was referenced Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Do not merge, and do not review. This is a throwaway draft that exists for one CI run. It will be closed and its branch deleted as soon as that run has been read.
It is the head of #1590 (
6e70778d) plus one commit that breaks the implementation on purpose in twenty places, so that the run records which of #1590's assertions go red when CI itself executes them. The per-mutation table in #1590 was measured locally, one mutation at a time; this run is the same evidence taken on the pull-request gate for a subset that one run can attribute.What is broken, and what is expected to go red
cargo test --doc --workspace)crates/sig/src/header_token.rscompile-fail probe, line 54CloneDefaultCloneDefaultVerdict::header_tokenis publicHeaderTokenvariant is constructible outside the cratetoken()accessorrustfs-gateway-core)request_context::tests::a_header_token_verdict_names_its_principal_and_no_signed_onerustfs-gateway,integration)Bearerfor authorizers and auditheader_token::a_verified_header_token_serves_the_request_as_the_principal_the_host_reportsheader_token::n_a_claim_without_a_verifier_refuses_and_never_serves_anonymouslyheader_token::n_the_token_beside_an_aws_credential_surface_is_refused_before_any_verifier_runsheader_token::n_a_verifier_that_panics_is_a_closed_403_and_poisons_nothingheader_token::n_a_header_token_verdict_from_another_admission_authenticates_nothingheader_token_secrecy::n_no_log_event_answer_or_context_holds_the_token,header_token_secrecy::n_a_panicking_verifier_is_reported_as_one_contained_panic_eventheader_token_secrecy::the_body_of_a_header_token_request_is_held_to_what_an_anonymous_body_isheader_token_secrecy::the_withheld_token_is_outside_the_accepted_head_and_classification_agreesrustfs_selection::n_an_unrouted_form_beside_a_header_token_is_neither_read_nor_verifiedcargo teststops at the first test binary that fails, so one run can show one red binary per job. The rules that onlyrustfs-gateway-sig's own integration tests pin (the value's shape, the claim's grammar, the operations predicate) are therefore not in this run:Workspace tests 3never reaches that binary once the facade's has failed.Other jobs may be red for reasons that are not evidence of anything:
Static checksbecause this body carries no role verdicts, andClippybecause the mutations are not written to its standard.