TAN-840: reload operator-staged assertion keys with scoped hosted authority - #1935
TAN-840: reload operator-staged assertion keys with scoped hosted authority#1935tacshade wants to merge 2 commits into
Conversation
Signed-off-by: TacShade <198919272+tacshade@users.noreply.github.com>
Signed-off-by: TacShade <198919272+tacshade@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 364d209264
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (kid, old) in before { | ||
| let new = after.get(&kid).ok_or("retain retired key metadata")?; |
There was a problem hiding this comment.
Reject aliases of retired or revoked key material
When a staged candidate retains a retired or revoked entry but adds an active entry under a new kid with the same Ed25519 public key, this loop compares lifecycle state only at the original kid, so the transition is accepted. Assertions signed by the supposedly revoked private key can then use the new kid and authenticate again, defeating monotonic retirement and revocation; reject active aliases of previously non-active decoded public keys.
Useful? React with 👍 / 👎.
| run: cargo test -p tandem-enterprise-contract hosted_policy --lib | ||
| - name: Validate scoped key lifecycle and administrative authority | ||
| run: | | ||
| cargo test -p tandem-server context_assertion_security --lib |
There was a problem hiding this comment.
The reviewed commit message has no Signed-off-by trailer, so it violates the repository's mandatory DCO policy and will not satisfy contribution checks; add the sign-off to this commit's metadata before publishing it.
AGENTS.md reference: AGENTS.md:L38-L39
Useful? React with 👍 / 👎.
| Self::ChannelConfigUpdate => "deployment.channels.manage", | ||
| Self::ChannelConfigDelete => "deployment.channels.manage", | ||
| Self::ChannelReload => "deployment.channels.reload", | ||
| Self::ContextAssertionReload => "hosted.admin", |
There was a problem hiding this comment.
Honor policy-projected hosted-admin grants
When the current hosted policy grants HostedAdmin through a member or organization-unit deployment_grant, the middleware projects that permission into strict_projection, but this host-action authorization checks only the assertion's raw capabilities for hosted.admin (or deployment.admin). A valid policy-granted hosted administrator therefore receives 403 unless the issuer redundantly embeds the capability; authorize this route against the projected AccessPermission::HostedAdmin authority as well.
Useful? React with 👍 / 👎.
| grant | ||
| .revalidate(&state, &effect) | ||
| .map_err(super::host_authority::host_authorization_status)?; | ||
| *current = Some(next); |
There was a problem hiding this comment.
Revalidate candidate key validity immediately before publishing
When the candidate's sole active key expires while the protected audit append is awaiting ledger verification and durable I/O, the handler still publishes it because active validity was checked only before that await. This installs a keyring with no usable key and rejects all subsequent hosted assertions; rerun the time-sensitive active-key validation immediately before assigning the snapshot.
Useful? React with 👍 / 👎.
Hosted administrators cannot use the existing full-config reload because it requires deployment.admin. Add POST /admin/context-assertions/reload through the existing verified hosted.admin authority, current policy and protected host-effect audit. The request accepts no key material, path, token setting or provider configuration.
Load only the operator-configured metadata keyring; retain the existing issuer/audience/lifetime and durable replay store. Validate deployment scope, active validity and immutable key material; keep retirement/revocation monotonic and retain old key metadata. Record the candidate fingerprints in protected audit before publishing, then revalidate authority and compare the previous snapshot to avoid a concurrent overwrite. Invalid candidates and audit failures leave the previous verifier live. A successful response reports the published fingerprint.
Stacks on #1934. Current364d2092 passed focused authority/regression CI and Engine CI. Exact-source non-root engine integration at agents0cd167a passed overlap, retirement, malformed/wrong-scope retention, unauthorized reload, audit-anchor failure and replay across restart. Web5ee9c37 consumes that bundle and passed its real Linux installer and signer tests. Security Assurance passed every job, including Linux release composition and final engine-container composition.
This is part of TAN-840 signing lifecycle, not completion of the whole issue. Encrypted clean-host recovery, broader two-user privacy and product acceptance remain open. No automatic merge.