security: add mock signer authority core - #23
Merged
Merged
Conversation
Owner
Author
|
Post-CI final diff review completed on exact head
The PR remains Draft for delayed final security review. No workflow activation or merge is requested. |
Owner
Author
|
Post-CI remediation diff review completed on exact head
The three Business B findings are remediated in this head, pending delayed independent security review. PR #23 remains Draft; no merge or workflow activation is requested. |
stacknil
marked this pull request as ready for review
September 18, 2026 15:43
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.
Problem
The signer v1 reference core needs to bind publication authority to the reviewed GitHub App/source and to GitHub's case-insensitive Commit Status context namespace. It also needs finalization token replay protection to survive later malformed controller evidence.
The reviewed head
0930522f2e5e02e631c03c349207b42ad7a59176left three Business B findings:PUBLICATION_SOURCE_BINDING;PUBLICATION_NAMESPACE_BINDING;JTI_GLOBAL_SINGLE_USE.This head remediates those three findings. Final approval remains subject to delayed independent review.
Invariant
(repository_id, policy_epoch)freezes exactly one(policy_digest, exact status_context, publisher_identity)tuple.(repository_id, normalized_status_context)is historically reserved to one policy epoch, including after revocation.(repository_id, head_oid, policy_epoch); publisher identity is immutable slot provenance, not an additional parallel slot dimension.Design decision
Epoch authority and physical context
The registry replaces digest-only epoch binding with an immutable epoch authority identity containing policy digest, exact status context, and publisher identity. Operational revisions may still change reviewed execution-only fields such as workflow SHA when that authority tuple is unchanged.
A second append-only mapping reserves each normalized physical status context to one epoch. Revocation releases neither mapping. Publisher/App rotation therefore requires an explicit reviewed epoch/context migration.
Publication source provenance
PublicationSlotstores publisher identity while retaining the existing semantic slot key. Reservation requires exact payload, digest, and source equality before any existing-published shortcut. A source mismatch returnspublication_source_conflictbefore provider access or evaluation publication.PublicationReceiptnow records publisher identity. Store transitions reject a matching payload digest from the wrong source withpublication_receipt_source_mismatch.MockPublishercreates receipts from its own identity and uses the normalized physical context key for publish and lookup.Publisher identity remains internal provenance and is not added to GitHub Commit Status payload fields or the canonical payload digest.
Finalization JTI consumption
After verified OIDC authorization, exact execution-tuple matching, and admission-token freshness checks, finalization atomically consumes the JTI before later evidence validation. Malformed evidence cannot leave that token reusable.
The design record states that a future durable store must commit JTI consumption as an independent security side effect rather than roll it back with a later parser refusal.
Threat / failure model
The focused regressions cover:
Rejected alternatives
Add publisher identity to the slot key.
Rejected because it would permit parallel A/B slots for one semantic authority epoch.
Encode publisher identity into GitHub status fields.
Rejected because source provenance is not part of the provider request payload.
Allow context reuse after revocation.
Rejected because historical provider statuses remain and could acquire a new authority meaning.
Depend on MockPublisher rejecting opposite payloads.
Rejected because GitHub accepts repeated status writes; registry/service invariants are tested with a permissive provider.
Consume finalization JTI after evidence parsing.
Rejected because authenticated malformed evidence would leave a reusable token.
Compatibility
The slot key, same-H cross-PR sharing, semantic verdict mapping, UNKNOWN state machine, admission idempotency, controller parser, OIDC architecture, acquisition, reader, materializer, scanner, baseline, report schemas, workflows, branch rules, and PR #22 remain unchanged.
Status contexts are deliberately narrowed to printable ASCII because the production authority context is ASCII and GitHub's physical namespace is case-insensitive.
Original exact base:
8e9e4c53a123bc285dd3f7c523427747326ab281Reviewed remediation base:
0930522f2e5e02e631c03c349207b42ad7a59176Exact head:
feb40fdbaf178a7688ecac3258384f0608f59dd9Validation
repo-sentinel-lite==0.8.1changed-file gate: 10 files, 0 findings;git diff --check: passed.Rollback
Revert the five remediation commits after
0930522f. No workflow, rule, credential, external status, production registry, or durable store depends on this mock core.PR #23 remains Draft and unmerged pending delayed final security review.