7 Commits
Author SHA1 Message Date
argoyle 3941ff4950 docs: deploy authz-service first when the /authz contract changes (#335)
Unbound Release / Check Preconditions (push) Successful in 26s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 50s
Unbound Release / Create Release (push) Successful in 29s
Release / release (push) Successful in 5m38s
2026-09-17 06:15:33 +00:00
argoyle e0d1ce3b31 fix!: order privilege events by sequence number and merge snapshots by position (#333)
Unbound Release / Check Preconditions (push) Successful in 27s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Create Release (push) Successful in 27s
authz_client / test (push) Successful in 1m10s
authz_client / vulnerabilities (push) Successful in 53s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 41s
Release / release (push) Successful in 1m10s
pre-commit / pre-commit (push) Successful in 3m12s
## Why
The privilege cache could keep a grant authz-service had revoked:
- **Unordered keys:** each routing key has its own transient queue, so a late `Privilege.Added`/`User.Added` resurrected a revoked grant.
- **Startup gap:** services fetched `/authz` before binding their queues, so revocations published in between were lost until restart.

Design: ADR-0015 (docs PR, Proposed).

## What
- `Process` orders events by authz-service's global `sequenceNo` per (email, company). All four events come from the Company aggregate, so seq order equals commit order. An event only overrides older facts, and `User.Removed` stamps every privilege.
- Events without a sequence number fail closed: additions are dropped, and removals hold until the next snapshot. Negative or huge sequence numbers are dropped.
- `Fetch` checks the status and retries 503 (60×1 s, 30 s HTTP timeout). It reads `X-Authz-Sequence`, merges the snapshot as facts at that position, and raises a floor; snapshots older than the floor are ignored. A missing header merges at 0 with a warning (rollout window only).
- `CompaniesByUser` returns `[]`, and unknown privileges create no state. CLAUDE.md is rewritten.

**BREAKING:** `Process` without `SequenceNo` no longer grants, so service tests must set it. Services must call `Fetch()` after `conn.Start`.

## Verification
- `go test -race`: 98.3% coverage, including table-driven reorderings, snapshot-merge cases and a revocation-during-Fetch race test.
- 26 mutants on the ordering, merge and retry checks: all killed (each compiled and produced `--- FAIL`).
- prek passes.

**Expert review:** two rounds. Round 1: Security, Go Backend, Event Sourcing and Database experts reviewed both diffs. Round 2: Security and Event Sourcing re-reviewed the fixes. A final Event Sourcing review covered the committed-events wrapper. Fixed from the reviews: older snapshots merged after newer ones (floor check); a lagging read view serving snapshots that miss revocations (503 plus catch-up); a reset's TRUNCATE emptying a REPEATABLE READ snapshot (LOCK TABLE privileges, verified on PostgreSQL); seq-0 removals undone by older additions (pending stamp); late-committing events skipped by read view backfills (CommittedEventStore with LOCK TABLE events IN SHARE MODE, verified on PostgreSQL 18); an unbounded lock wait (lock_timeout plus retries); catch-up firing on ordinary lag (5 s stall, 10 s cooldown, 10 min deadline); plus smaller items (unknown privileges, invalid seqs, `require` in a goroutine, wrapped errors, `[]` not nil). **Deliberately deferred (tracked in Ambix):** stored-but-unpublished revocations (user decision: authz-service outbox); the readview library's commit-order gap for other services (upstream); removing the missing-header fallback and alerting on /authz 503s; moving Fetch after conn.Start in the 13 consumers (separate bump PRs).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01DVGsVQ8AMFR4NZoxyCoEqS
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/333
2026-09-16 18:36:07 +00:00
argoyle 01f30cfd2b fix: keep existing privileges when User.Added is processed late (#331)
authz_client / test (push) Successful in 58s
Unbound Release / Check Preconditions (push) Successful in 22s
Unbound Release / Create Tag (push) Skipped
authz_client / vulnerabilities (push) Successful in 47s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 32s
Unbound Release / Create Release (push) Successful in 24s
Release / release (push) Successful in 58s
pre-commit / pre-commit (push) Successful in 2m17s
2026-09-16 05:19:03 +00:00
argoyle 6bdf6e1cd3 feat!: consume privilege events with go-messaging-amqp (#327)
Unbound Release / Create Tag (push) Skipped
Unbound Release / Check Preconditions (push) Successful in 29s
authz_client / vulnerabilities (push) Skipped
authz_client / test (push) Skipped
pre-commit / pre-commit (push) Successful in 2m36s
Unbound Release / Create Release (push) Successful in 40s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 37s
Release / release (push) Successful in 2m24s
2026-09-11 21:00:41 +00:00
argoyle 60d9eea9c9 chore: migrate module path to gitea.unbound.se
authz_client / test (pull_request) Successful in 1m56s
authz_client / vulnerabilities (pull_request) Successful in 2m31s
pre-commit / pre-commit (pull_request) Successful in 5m21s
Update module path from git.unbound.se to gitea.unbound.se for Go module
discovery over HTTPS.
2026-01-09 14:30:26 +01:00
argoyle 681afe2626 refactor: update module path to new repository location
authz_client / test (pull_request) Successful in 3m25s
authz_client / vulnerabilities (pull_request) Successful in 3m42s
Remove GitLab CI linter configuration and update module path from 
`gitlab.com/unboundsoftware/shiny/authz_client` to 
`git.unbound.se/shiny/authz_client` in all relevant files. 
These changes reflect a migration to a new hosting service.
2026-01-09 09:28:16 +01:00
argoyle 1fd3ae5123 docs: add CLAUDE.md for Claude Code integration 2025-12-31 22:06:51 +01:00