feat: store principal invalidation records - #10
Draft
pyropy wants to merge 1 commit into
Draft
Conversation
RevocationStore gains AddPrincipalRevocation, which records that every proof cached for a principal's keys is void. Both backends reject an undefined tenant or an empty principal and otherwise mirror Add. Postgres stores the records in a new principal_invalidation table (migration 00002) and reads both tables in one UNION ALL ordered by recorded_at and id, so the stream keeps one now() horizon, one cursor and one dedup map across both kinds. The memory backend appends to the same log Stream already reads. Get is unaffected: it reads only the revocation table. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pyropy
added this pull request to stack #12
September 10, 2026 16:19
pyropy
force-pushed
the
srdjan/feat/iam-principal-records
branch
from
September 11, 2026 12:40
9507aca to
bf74330
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Critical PostgreSQL streaming and firehose compatibility issues remain unresolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds principal invalidation persistence and unified streaming across memory and PostgreSQL backends.
Changes:
- Extends the store API with
AddPrincipalRevocation. - Adds PostgreSQL schema, storage, and unified polling.
- Adds backend and validation tests.
File summaries
| File | Summary |
|---|---|
pkg/store/store.go |
Extends the store interface. |
pkg/store/postgres/store.go |
Persists and streams principal invalidations. |
pkg/store/postgres/store_test.go |
Tests PostgreSQL behavior. |
pkg/store/postgres/migrations/sql/00002_principal_invalidation.sql |
Adds the invalidation table and index. |
pkg/store/memory/store.go |
Adds in-memory support. |
pkg/store/memory/store_test.go |
Tests in-memory behavior. |
pkg/fx/app_test.go |
Updates the test store implementation. |
Review details
Suppressed comments (1)
pkg/store/postgres/store.go:208
- The UNION now permits the same invocation CID to exist once in each table: the primary keys are table-local and both
Addmethods accept the same invocation. However, the sharedseenmap below is keyed only byrec.Cause().Link(), so recording both effects with one invocation silently drops the second event even thoughStreampromises all records. Key deduplication by record kind plus cause, and prune the same composite key.
`SELECT kind, cause, revoked_delegation, path_witness, tenant, principal, recorded_at
- Files reviewed: 7/7 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| s.mu.Lock() | ||
| defer s.mu.Unlock() | ||
| record.RecordedAt = time.Now() // under the lock, as in Add | ||
| s.appendLocked(store.PrincipalRevocationEvent(record)) |
| FROM principal_invalidation | ||
| WHERE recorded_at >= $1 | ||
| ) AS record | ||
| ORDER BY recorded_at, id`, |
| yield(store.Event{}, fmt.Errorf("decoding principal invalidation: %w", err)) | ||
| return | ||
| } | ||
| event = store.PrincipalRevocationEvent(record) |
Comment on lines
+105
to
+108
| // AddPrincipalRevocation adds a principal invalidation record to the store. | ||
| // The invalidation is the invocation that voids every proof cached for the | ||
| // principal's keys; tenant must be defined and principal must not be empty. | ||
| AddPrincipalRevocation(ctx context.Context, invalidation ucan.Invocation, tenant did.DID, principal string) error |
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.
Description
RevocationStoregainsAddPrincipalRevocation, recording that every proof a gateway cached for a principal's keys is void. Postgres reads both tables in oneUNION ALLordered byrecorded_at, keeping a single horizon, cursor and dedup map.GET /revocation/:cidis unchanged. Part of the Forge S3 tenant IAM work (RFC).Change log
AddPrincipalRevocationon the interface and both backendsprincipal_invalidationtable and index🤖 Generated with Claude Code