138 Commits
Author SHA1 Message Date
argoyle 6a708965e4 chore(renovate): group OpenTelemetry, otelsetup and logging updates (#343)
Unbound Release / Check Preconditions (push) Successful in 21s
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 38s
Unbound Release / Create Release (push) Successful in 36s
Release / release (push) Successful in 4m48s
2026-10-05 10:29:00 +00:00
renovate bb450e5d8c chore(deps): update pre-commit hook golangci/golangci-lint to v2.14.0 (#341)
Unbound Release / Check Preconditions (push) Successful in 27s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Create Release (push) Successful in 28s
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 52s
Release / release (push) Successful in 21m31s
2026-09-27 12:09:00 +00:00
renovate 206d2ab14b chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.27.0 (#339)
Unbound Release / Check Preconditions (push) Successful in 26s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 43s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Create Release (push) Successful in 28s
Release / release (push) Successful in 11m17s
2026-09-23 19:19:20 +00:00
renovate 78b4730687 fix(deps): update module codeberg.org/messaging/go-messaging-amqp to v0.0.6 (#337)
Unbound Release / Check Preconditions (push) Successful in 26s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 42s
Release / release (push) Successful in 6m44s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Create Release (push) Successful in 28s
2026-09-20 11:08:10 +00:00
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
releaser 09766ebe8b chore(release): prepare for v0.7.0 (#334)
Unbound Release / Check Preconditions (push) Successful in 27s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 29s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
Unbound Release / Create Release (push) Successful in 30s
Release / release (push) Successful in 1m15s
pre-commit / pre-commit (push) Successful in 3m11s
## [0.7.0] - 2026-09-16

### 🐛 Bug Fixes

- [**breaking**] Order privilege events by sequence number and merge snapshots by position (#333)

<!-- generated by git-cliff -->

---

**Note:** Please use **Squash Merge** when merging this PR.

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/334
Co-authored-by: Unbound Releaser <releaser@unbound.se>
2026-09-16 18:40:41 +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
releaser 5100d53c76 chore(release): prepare for v0.6.1 (#332)
Unbound Release / Create Release (push) Successful in 24s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 29s
Release / release (push) Successful in 55s
Unbound Release / Check Preconditions (push) Successful in 21s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
Unbound Release / Create Tag (push) Skipped
pre-commit / pre-commit (push) Successful in 2m34s
Co-authored-by: Unbound Releaser <releaser@unbound.se>
2026-09-16 05:24:06 +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
releaser 9d1b981644 chore(release): prepare for v0.6.0 (#330)
Unbound Release / Check Preconditions (push) Successful in 26s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 28s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
Release / release (push) Successful in 1m5s
Unbound Release / Create Release (push) Successful in 30s
pre-commit / pre-commit (push) Successful in 3m3s
## [0.6.0] - 2026-09-11

### 🚀 Features

- [**breaking**] Consume privilege events with go-messaging-amqp (#327)

### ⚙️ Miscellaneous Tasks

- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.2 (#325)
- Bump the minor version for breaking changes before 1.0.0 (#328)

<!-- generated by git-cliff -->

---

**Note:** Please use **Squash Merge** when merging this PR.

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/330
Co-authored-by: Unbound Releaser <releaser@unbound.se>
2026-09-14 06:50:03 +00:00
argoyle 3347d598a4 chore: bump the minor version for breaking changes before 1.0.0 (#328)
authz_client / test (push) Skipped
Unbound Release / Check Preconditions (push) Successful in 31s
Unbound Release / Create Tag (push) Skipped
authz_client / vulnerabilities (push) Skipped
Release / release (push) Successful in 1m25s
pre-commit / pre-commit (push) Successful in 2m26s
Unbound Release / Create Release (push) Successful in 23s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 39s
2026-09-11 21:05:52 +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
renovate f5e9eb52a7 chore(deps): update pre-commit hook golangci/golangci-lint to v2.13.2 (#325)
Unbound Release / Check Preconditions (push) Successful in 22s
Unbound Release / Create Tag (push) Skipped
authz_client / test (push) Skipped
Release / release (push) Successful in 4m57s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 36s
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Unbound Release / Create Release (push) Successful in 24s
2026-08-31 00:08:45 +00:00
releaser 85d29c1196 chore(release): prepare for v0.5.1 (#324)
Unbound Release / Check Preconditions (push) Successful in 31s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 29s
Unbound Release / Create Release (push) Successful in 31s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Skipped
Release / release (push) Successful in 6m25s
## [0.5.1] - 2026-08-21

### 🐛 Bug Fixes

- *(ci)* Use go-test-coverage binary directly to fix Gitea Actions (#303)
- *(deps)* Update module github.com/stretchr/testify to v1.12.0 (#319)
- *(deps)* Update module github.com/stretchr/testify to v1.12.1 (#321)

### ⚙️ Miscellaneous Tasks

- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.30.1 (#296)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.4 (#298)
- *(deps)* Update dependency go to v1.26.2 (#300)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.25.0 (#304)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.0 (#306)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.1 (#308)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.2 (#309)
- *(deps)* Update actions/checkout action to v7 (#311)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.26.0 (#313)
- *(deps)* Update actions/setup-go action to v7 (#315)
- *(deps)* Update actions/setup-python action to v7 (#317)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.1 (#322)

<!-- generated by git-cliff -->

---

**Note:** Please use **Squash Merge** when merging this PR.

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/324
Co-authored-by: Unbound Releaser <releaser@unbound.se>
2026-08-29 11:26:44 +00:00
renovate 37d9282f7e fix(deps): update module github.com/stretchr/testify to v1.12.1 (#321)
Unbound Release / Check Preconditions (push) Successful in 21s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Generate Changelog and Handle PR (push) Successful in 39s
Release / release (push) Successful in 3m36s
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Successful in 3m14s
Unbound Release / Create Release (push) Successful in 53s
2026-08-21 13:03:06 +00:00
renovate 5c2477eded chore(deps): update pre-commit hook golangci/golangci-lint to v2.13.1 (#322)
authz_client / test (push) Skipped
authz_client / vulnerabilities (push) Skipped
pre-commit / pre-commit (push) Successful in 2m8s
Unbound Release / Create Tag (push) Skipped
Unbound Release / Create Release (push) Successful in 24s
Unbound Release / Check Preconditions (push) Successful in 30s
Unbound Release / Generate Changelog and Handle PR (push) Successful in 48s
Release / release (push) Successful in 1m20s
2026-08-21 12:08:18 +00:00
renovate bfd5fd4c16 fix(deps): update module github.com/stretchr/testify to v1.12.0 (#319)
Unbound Release / Check Preconditions (push) Successful in 21s
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 53s
Release / release (push) Successful in 47m10s
Unbound Release / Create Release (push) Successful in 24s
2026-08-17 09:09:30 +00:00
renovate dfc666ebb0 chore(deps): update actions/setup-python action to v7 (#317)
Unbound Release / Check Preconditions (push) Successful in 25s
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 51s
Unbound Release / Create Release (push) Successful in 42s
Release / release (push) Successful in 19m15s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-python](https://github.com/actions/setup-python) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/setup-python (actions/setup-python)</summary>

### [`v7.0.0`](https://github.com/actions/setup-python/releases/tag/v7.0.0)

[Compare Source](https://github.com/actions/setup-python/compare/v7.0.0...v7.0.0)

#### What's Changed

##### Enhancements

- Migrate to ESM and upgrade dependencies by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;1330](https://github.com/actions/setup-python/pull/1330)
- Pin SHA commits and update docs with latest versions by [@&#8203;HarithaVattikuti](https://github.com/HarithaVattikuti) in [#&#8203;1338](https://github.com/actions/setup-python/pull/1338)
- Remove the pip-install input by [@&#8203;gowridurgad](https://github.com/gowridurgad) in [#&#8203;1336](https://github.com/actions/setup-python/pull/1336)

##### Bug Fix

- Fix to Classify stderr warning messages as warnings instead of errors in annotations by [@&#8203;lmvysakh](https://github.com/lmvysakh) in [#&#8203;1335](https://github.com/actions/setup-python/pull/1335)
- Validate and retry manifest fetch to prevent silent failures by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;1332](https://github.com/actions/setup-python/pull/1332)

##### Dependency Upgrade

- Bump certifi from 2020.6.20 to 2024.7.4 in /**tests**/data by [@&#8203;dependabot](https://github.com/dependabot) in [#&#8203;1328](https://github.com/actions/setup-python/pull/1328)
- Remove EOL Python versions and Bumps numpy text fixture by [@&#8203;priya-kinthali](https://github.com/priya-kinthali) in [#&#8203;1333](https://github.com/actions/setup-python/pull/1333)
- Upgrade [@&#8203;actions/cache](https://github.com/actions/cache) to 6.2.0 by [@&#8203;philip-gai](https://github.com/philip-gai) in [#&#8203;1337](https://github.com/actions/setup-python/pull/1337)

#### New Contributors

- [@&#8203;lmvysakh](https://github.com/lmvysakh) made their first contribution in [#&#8203;1335](https://github.com/actions/setup-python/pull/1335)
- [@&#8203;philip-gai](https://github.com/philip-gai) made their first contribution in [#&#8203;1337](https://github.com/actions/setup-python/pull/1337)

**Full Changelog**: <https://github.com/actions/setup-python/compare/v6...v7.0.0>

### [`v7`](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0)

[Compare Source](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTcuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI1Ny4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/317

Co-authored-by: Renovate Bot <renovate@unbound.se>
2026-07-25 11:38:17 +00:00
renovate 75f87fd618 chore(deps): update actions/setup-go action to v7 (#315)
Release / release (push) Successful in 49s
authz_client / test (push) Successful in 1m4s
authz_client / vulnerabilities (push) Successful in 50s
pre-commit / pre-commit (push) Successful in 3m1s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-go](https://github.com/actions/setup-go) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/setup-go (actions/setup-go)</summary>

### [`v7.0.0`](https://github.com/actions/setup-go/releases/tag/v7.0.0)

[Compare Source](https://github.com/actions/setup-go/compare/v7.0.0...v7.0.0)

##### What's Changed

- Migrate to ESM and upgrade dependencies by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;763](https://github.com/actions/setup-go/pull/763)
- chore(deps): bump [@&#8203;actions/cache](https://github.com/actions/cache) to 6.2.0 by [@&#8203;philip-gai](https://github.com/philip-gai) in [#&#8203;771](https://github.com/actions/setup-go/pull/771)

##### New Contributors

- [@&#8203;philip-gai](https://github.com/philip-gai) made their first contribution in [#&#8203;771](https://github.com/actions/setup-go/pull/771)

**Full Changelog**: <https://github.com/actions/setup-go/compare/v6...v7.0.0>

### [`v7`](https://github.com/actions/setup-go/compare/v6.5.0...v7.0.0)

[Compare Source](https://github.com/actions/setup-go/compare/v6.5.0...v7.0.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDMuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0My4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/315
Co-authored-by: Renovate Bot <renovate@unbound.se>
Co-committed-by: Renovate Bot <renovate@unbound.se>
2026-07-19 18:55:40 +00:00
renovate 752f80ea96 chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.26.0 (#313)
authz_client / test (push) Successful in 1m43s
authz_client / vulnerabilities (push) Successful in 58s
Release / release (push) Successful in 48s
pre-commit / pre-commit (push) Successful in 4m5s
2026-06-27 23:27:40 +00:00
renovate 08269c034b chore(deps): update actions/checkout action to v7 (#311)
Release / release (push) Successful in 1m0s
authz_client / test (push) Successful in 2m6s
authz_client / vulnerabilities (push) Successful in 2m13s
pre-commit / pre-commit (push) Successful in 5m42s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://github.com/actions/checkout) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/checkout (actions/checkout)</summary>

### [`v7.0.0`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v700)

[Compare Source](https://github.com/actions/checkout/compare/v7.0.0...v7.0.0)

- Block checking out fork PR for pull\_request\_target and workflow\_run by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2454](https://github.com/actions/checkout/pull/2454)
- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2458](https://github.com/actions/checkout/pull/2458)
- Bump flatted from 3.3.1 to 3.4.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2460](https://github.com/actions/checkout/pull/2460)
- Bump js-yaml from 4.1.0 to 4.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2461](https://github.com/actions/checkout/pull/2461)
- Bump [@&#8203;actions/core](https://github.com/actions/core) and [@&#8203;actions/tool-cache](https://github.com/actions/tool-cache) and Remove uuid by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2459](https://github.com/actions/checkout/pull/2459)
- upgrade module to esm and update dependencies by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2463](https://github.com/actions/checkout/pull/2463)
- Bump the minor-npm-dependencies group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2462](https://github.com/actions/checkout/pull/2462)

### [`v7`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v700)

[Compare Source](https://github.com/actions/checkout/compare/v6.0.3...v7.0.0)

- Block checking out fork PR for pull\_request\_target and workflow\_run by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2454](https://github.com/actions/checkout/pull/2454)
- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2458](https://github.com/actions/checkout/pull/2458)
- Bump flatted from 3.3.1 to 3.4.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2460](https://github.com/actions/checkout/pull/2460)
- Bump js-yaml from 4.1.0 to 4.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2461](https://github.com/actions/checkout/pull/2461)
- Bump [@&#8203;actions/core](https://github.com/actions/core) and [@&#8203;actions/tool-cache](https://github.com/actions/tool-cache) and Remove uuid by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2459](https://github.com/actions/checkout/pull/2459)
- upgrade module to esm and update dependencies by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2463](https://github.com/actions/checkout/pull/2463)
- Bump the minor-npm-dependencies group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2462](https://github.com/actions/checkout/pull/2462)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMjAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIyMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/311
Co-authored-by: Renovate Bot <renovate@unbound.se>
Co-committed-by: Renovate Bot <renovate@unbound.se>
2026-06-21 15:45:38 +00:00
renovate 89fa8928dc chore(deps): update pre-commit hook golangci/golangci-lint to v2.12.2 (#309)
Release / release (push) Successful in 1m8s
authz_client / vulnerabilities (push) Successful in 1m36s
authz_client / test (push) Successful in 2m23s
pre-commit / pre-commit (push) Successful in 5m56s
2026-05-09 13:27:43 +00:00
renovate 6fccd2010c chore(deps): update pre-commit hook golangci/golangci-lint to v2.12.1 (#308)
Release / release (push) Failing after 1m1s
authz_client / vulnerabilities (push) Successful in 1m30s
authz_client / test (push) Successful in 2m18s
pre-commit / pre-commit (push) Successful in 5m13s
2026-05-04 17:07:50 +00:00
renovate 4296334275 chore(deps): update pre-commit hook golangci/golangci-lint to v2.12.0 (#306)
Release / release (push) Successful in 1m5s
authz_client / vulnerabilities (push) Successful in 1m56s
authz_client / test (push) Successful in 2m41s
pre-commit / pre-commit (push) Successful in 6m8s
2026-05-04 14:07:07 +00:00
renovate daa836e97d chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.25.0 (#304)
authz_client / test (push) Successful in 2m23s
authz_client / vulnerabilities (push) Successful in 1m32s
Release / release (push) Successful in 53s
pre-commit / pre-commit (push) Successful in 5m53s
2026-05-03 16:17:20 +00:00
argoyle f9a89b64be fix(ci): use go-test-coverage binary directly to fix Gitea Actions (#303)
authz_client / vulnerabilities (push) Successful in 1m37s
Release / release (push) Failing after 1m2s
authz_client / test (push) Successful in 2m44s
pre-commit / pre-commit (push) Failing after 14m25s
## Summary

- `vladopajic/go-test-coverage@v2` (v2.18.5+, released 2026-04-26/27) restructured its composite action to pass inputs via env-var mapping. Gitea `act_runner` doesn't expand `${{ }}` expressions inside docker-action `env:` blocks reliably, so the literal string `${{ inputs.config }}` reached the binary and broke the 'Check coverage' step.
- Replace the action with a direct `go install` + binary invocation (matching the established Frostmoln pattern).
- Use `--github-action-output` to expose `total-coverage` as a step output, replacing the manual `go tool cover -func | grep | awk` calculations.
- Baseline artifact now stores the percentage directly instead of the full coverage profile.
- Bump `go` directive in `go.mod` from 1.22.12 → 1.26.2 (matching toolchain) — we are the sole consumers of this module.

## Test plan

- [x] `prek run --all-files` passes
- [ ] CI passes on this PR
- [ ] After merge, baseline artifact format propagates on next push to main

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/303
2026-04-29 06:06:22 +00:00
renovate 775d25cb59 chore(deps): update dependency go to v1.26.2 (#300)
authz_client / vulnerabilities (push) Successful in 1m46s
Release / release (push) Successful in 1m0s
authz_client / test (push) Successful in 2m10s
pre-commit / pre-commit (push) Successful in 6m1s
2026-04-10 00:13:25 +00:00
renovate ef992cb9db chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.4 (#298)
Release / release (push) Successful in 1m6s
authz_client / vulnerabilities (push) Successful in 1m38s
authz_client / test (push) Successful in 2m18s
pre-commit / pre-commit (push) Successful in 6m1s
2026-03-22 18:11:14 +00:00
renovate c3b8a3f1ce chore(deps): update pre-commit hook gitleaks/gitleaks to v8.30.1 (#296)
authz_client / vulnerabilities (push) Successful in 2m10s
Release / release (push) Successful in 1m29s
authz_client / test (push) Successful in 3m0s
pre-commit / pre-commit (push) Successful in 7m11s
2026-03-12 16:09:43 +00:00
releaser 45512115c5 chore(release): prepare for v0.5.0 (#295)
Release / release (push) Successful in 40s
authz_client / vulnerabilities (push) Successful in 1m23s
authz_client / test (push) Successful in 2m1s
pre-commit / pre-commit (push) Successful in 4m10s
## [0.5.0] - 2026-03-12

### 🚀 Features

- *(client)* Add API key authentication for /authz endpoint (#294)

### ⚙️ Miscellaneous Tasks

- *(deps)* Update golang:1.25.5 docker digest to 3a01526 (#271)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.24.0 (#273)
- *(deps)* Update dependency go to v1.25.6 (#274)
- *(deps)* Update golang docker tag to v1.25.6 (#275)
- Remove GitLab CI configuration
- Add code coverage integration
- *(deps)* Update dependency go to v1.25.7 (#279)
- *(deps)* Update dependency go to v1.26.0 (#280)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.9.0 (#281)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.0 (#282)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.1 (#283)
- *(deps)* Update dependency go to v1.26.1 (#286)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.1 (#288)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.2 (#290)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.3 (#292)

<!-- generated by git-cliff -->

---

**Note:** Please use **Squash Merge** when merging this PR.

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/295
Co-authored-by: Unbound Releaser <releaser@unbound.se>
Co-committed-by: Unbound Releaser <releaser@unbound.se>
2026-03-12 07:39:47 +00:00
argoyle fe0abd62c8 feat(client): add API key authentication for /authz endpoint (#294)
Release / release (push) Successful in 1m15s
authz_client / vulnerabilities (push) Successful in 2m9s
authz_client / test (push) Successful in 2m21s
pre-commit / pre-commit (push) Successful in 4m46s
## Summary

- Add `WithAPIKey(key string)` option to `PrivilegeHandler`
- When set, `Fetch()` sends `Authorization: Bearer <key>` header
- Backward compatible: no key = no header (existing behavior)

## Test plan

- [x] Unit test verifying Authorization header is sent
- [x] Unit test verifying no header without key
- [x] Existing tests still pass

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

Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/294
2026-03-12 07:32:12 +00:00
renovate a54cf45a4b chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.3 (#292)
Release / release (push) Successful in 1m21s
authz_client / vulnerabilities (push) Successful in 2m9s
authz_client / test (push) Successful in 4m40s
pre-commit / pre-commit (push) Successful in 7m39s
2026-03-10 11:12:34 +00:00
renovate f9a5ef7085 chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.2 (#290)
authz_client / vulnerabilities (push) Failing after 2h42m46s
authz_client / test (push) Failing after 2h42m53s
pre-commit / pre-commit (push) Successful in 4m44s
Release / release (push) Successful in 1m2s
2026-03-07 22:09:47 +00:00
renovate 200e7cf963 chore(deps): update pre-commit hook golangci/golangci-lint to v2.11.1 (#288)
authz_client / test (push) Successful in 2m49s
Release / release (push) Successful in 57s
authz_client / vulnerabilities (push) Successful in 1m46s
pre-commit / pre-commit (push) Successful in 5m49s
2026-03-06 15:11:17 +00:00
renovate 110f6206f9 chore(deps): update dependency go to v1.26.1 (#286)
Release / release (push) Successful in 1m13s
authz_client / vulnerabilities (push) Successful in 1m36s
authz_client / test (push) Successful in 2m27s
pre-commit / pre-commit (push) Successful in 10m39s
2026-03-06 01:18:10 +00:00
renovate c53d80792c chore(deps): update pre-commit hook golangci/golangci-lint to v2.10.1 (#283)
Release / release (push) Successful in 1m31s
authz_client / vulnerabilities (push) Successful in 2m39s
authz_client / test (push) Successful in 3m54s
pre-commit / pre-commit (push) Successful in 8m34s
2026-02-17 17:01:30 +00:00
renovate ebc0c3bb8e chore(deps): update pre-commit hook golangci/golangci-lint to v2.10.0 (#282)
authz_client / vulnerabilities (push) Successful in 17m19s
authz_client / test (push) Successful in 18m59s
pre-commit / pre-commit (push) Successful in 52m24s
Release / release (push) Failing after 41s
2026-02-17 15:01:11 +00:00
renovate cb59762fc9 chore(deps): update pre-commit hook golangci/golangci-lint to v2.9.0 (#281)
authz_client / vulnerabilities (push) Successful in 2m12s
authz_client / test (push) Successful in 4m10s
Release / release (push) Successful in 1m55s
pre-commit / pre-commit (push) Successful in 17m58s
2026-02-11 07:13:35 +00:00
renovate a82466cb27 chore(deps): update dependency go to v1.26.0 (#280)
authz_client / vulnerabilities (push) Successful in 4m20s
authz_client / test (push) Successful in 4m30s
Release / release (push) Successful in 1m22s
pre-commit / pre-commit (push) Successful in 9m2s
2026-02-11 06:19:26 +00:00
renovate 29eab978f7 chore(deps): update dependency go to v1.25.7 (#279)
Release / release (push) Failing after 58s
authz_client / test (push) Successful in 4m30s
authz_client / vulnerabilities (push) Successful in 3m54s
pre-commit / pre-commit (push) Successful in 12m54s
2026-02-04 16:16:32 +00:00
argoyle f3166426b6 Merge pull request 'ci: add code coverage integration' (#277) from ci-coverage-integration into main
Release / release (push) Failing after 4m57s
authz_client / vulnerabilities (push) Successful in 7m21s
authz_client / test (push) Successful in 8m12s
pre-commit / pre-commit (push) Successful in 14m37s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/277
2026-01-28 12:38:20 +00:00
argoyleandClaude Opus 4.5 3171c53393 ci: add code coverage integration
authz_client / test (pull_request) Successful in 6m57s
authz_client / vulnerabilities (pull_request) Successful in 7m26s
pre-commit / pre-commit (pull_request) Successful in 12m3s
Add go-test-coverage for coverage threshold enforcement. Coverage data
is uploaded as artifacts on main branch and compared against baseline
in PRs using shell script that gracefully handles first run without
baseline. PR comments show coverage percentage.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 13:03:07 +01:00
argoyle 7af8e00b4c Merge pull request 'chore: remove GitLab CI configuration' (#276) from remove-gitlab-ci into main
pre-commit / pre-commit (push) Successful in 7m12s
authz_client / vulnerabilities (push) Successful in 10m29s
authz_client / test (push) Successful in 2m49s
Release / release (push) Failing after 1m59s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/276
2026-01-18 20:15:35 +00:00
argoyle 0c0f321b33 chore: remove GitLab CI configuration
authz_client / test (pull_request) Successful in 6m42s
authz_client / vulnerabilities (pull_request) Successful in 9m50s
pre-commit / pre-commit (pull_request) Successful in 18m32s
2026-01-18 20:36:13 +01:00
renovate 87805f1552 chore(deps): update golang docker tag to v1.25.6 (#275)
authz_client / test (push) Successful in 2m27s
Release / release (push) Successful in 2m49s
pre-commit / pre-commit (push) Successful in 5m23s
authz_client / vulnerabilities (push) Successful in 1m28s
2026-01-15 22:06:58 +00:00
renovate 74ee30bccc chore(deps): update dependency go to v1.25.6 (#274)
Release / release (push) Successful in 2m33s
authz_client / test (push) Successful in 4m27s
authz_client / vulnerabilities (push) Successful in 6m55s
pre-commit / pre-commit (push) Successful in 15m1s
2026-01-15 20:06:38 +00:00
renovate 646e4f31c4 chore(deps): update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.24.0 (#273)
Release / release (push) Successful in 2m12s
authz_client / vulnerabilities (push) Successful in 6m17s
pre-commit / pre-commit (push) Successful in 17m3s
authz_client / test (push) Successful in 5m48s
2026-01-13 21:08:37 +00:00
renovate 881fac379f chore(deps): update golang:1.25.5 docker digest to 3a01526 (#271)
authz_client / test (push) Successful in 2m23s
authz_client / vulnerabilities (push) Successful in 2m32s
Release / release (push) Successful in 1m57s
pre-commit / pre-commit (push) Successful in 6m25s
2026-01-13 14:35:12 +00:00
argoyle 2c2bd2798f Merge pull request 'chore(release): prepare for v0.4.1' (#270) from next-release into main
authz_client / test (push) Successful in 1m42s
Release / release (push) Successful in 48s
authz_client / vulnerabilities (push) Successful in 1m41s
pre-commit / pre-commit (push) Successful in 4m20s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/270
2026-01-09 14:05:17 +00:00
releaser 204b108ece chore(release): prepare for v0.4.1
pre-commit / pre-commit (pull_request) Successful in 5m37s
authz_client / vulnerabilities (pull_request) Successful in 3m36s
authz_client / test (pull_request) Successful in 3m27s
2026-01-09 13:57:10 +00:00
releaser fa795a58cf chore(release): prepare for v0.4.1 2026-01-09 13:57:03 +00:00
argoyle 60650b9c04 Merge pull request 'chore: migrate module path to gitea.unbound.se' (#269) from migrate-to-gitea into main
pre-commit / pre-commit (push) Has been cancelled
Release / release (push) Successful in 4m58s
authz_client / test (push) Successful in 4m45s
authz_client / vulnerabilities (push) Successful in 4m55s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/269
2026-01-09 13:50:03 +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 dd571f8d85 Merge pull request 'chore(deps): update actions/setup-python action to v6' (#268) from renovate/actions-setup-python-6.x into main
authz_client / vulnerabilities (push) Successful in 3m7s
authz_client / test (push) Successful in 3m36s
pre-commit / pre-commit (push) Successful in 5m22s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/268
2026-01-09 09:28:58 +00:00
renovate 1f822b2957 chore(deps): update actions/setup-python action to v6
authz_client / vulnerabilities (pull_request) Successful in 5m33s
pre-commit / pre-commit (pull_request) Successful in 9m6s
authz_client / test (pull_request) Successful in 5m50s
2026-01-09 09:01:53 +00:00
argoyle 5b49b36a32 Merge pull request 'chore(release): prepare for v0.4.0' (#244) from next-release into main
Release / release (push) Successful in 1m17s
authz_client / test (push) Successful in 2m41s
authz_client / vulnerabilities (push) Successful in 2m41s
pre-commit / pre-commit (push) Successful in 4m51s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/244
2026-01-09 08:57:37 +00:00
releaser a06bae1da9 chore(release): prepare for v0.4.0 2026-01-09 08:55:47 +00:00
releaser 90084cc3a4 chore(release): prepare for v0.4.0 2026-01-09 08:55:36 +00:00
argoyle 7825fa17a6 Merge pull request 'ci: add pre-commit and release workflows' (#266) from add-workflows into main
authz_client / vulnerabilities (push) Successful in 1m30s
Release / release (push) Successful in 1m10s
authz_client / test (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/266
2026-01-09 08:53:38 +00:00
argoyle 73f854ba06 ci: add pre-commit and release workflows
authz_client / test (pull_request) Successful in 3m9s
authz_client / vulnerabilities (pull_request) Successful in 3m53s
pre-commit / pre-commit (pull_request) Successful in 7m22s
2026-01-09 09:45:06 +01:00
argoyle 5b3527439f Merge pull request 'refactor: update module path to new repository location' (#267) from refactor-update-module-path into main
authz_client / vulnerabilities (push) Successful in 3m12s
authz_client / test (push) Successful in 4m3s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/267
2026-01-09 08:44:53 +00: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 2e1eb327e0 Merge pull request 'chore(deps): update pre-commit hook golangci/golangci-lint to v2.8.0' (#265) from renovate/golangci-golangci-lint-2.x into main
authz_client / test (push) Successful in 1m1s
authz_client / vulnerabilities (push) Successful in 1m2s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/265
2026-01-09 04:11:30 +00:00
renovate 622d907e03 chore(deps): update pre-commit hook golangci/golangci-lint to v2.8.0
authz_client / vulnerabilities (pull_request) Successful in 1m45s
authz_client / test (pull_request) Successful in 1m47s
2026-01-08 21:02:44 +00:00
argoyle 4b38ce4f0f Merge pull request 'chore(deps): update actions/checkout action to v6' (#264) from renovate/actions-checkout-6.x into main
authz_client / test (push) Successful in 3m55s
authz_client / vulnerabilities (push) Successful in 4m13s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/264
2026-01-08 19:21:16 +00:00
renovate b82e15c49b chore(deps): update actions/checkout action to v6
authz_client / test (pull_request) Successful in 1m16s
authz_client / vulnerabilities (pull_request) Successful in 1m14s
2026-01-08 19:01:10 +00:00
argoyle f0ea0d7d26 Merge pull request 'chore(deps): update actions/setup-go action to v6' (#263) from renovate/actions-setup-go-6.x into main
authz_client / test (push) Successful in 2m42s
authz_client / vulnerabilities (push) Successful in 3m32s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/263
2026-01-08 18:28:51 +00:00
renovate 26de10c2b9 chore(deps): update actions/setup-go action to v6
authz_client / test (pull_request) Successful in 1m53s
authz_client / vulnerabilities (pull_request) Successful in 1m57s
2026-01-08 18:01:11 +00:00
argoyle 3865b1b5f7 Merge pull request 'feat: migrate from GitLab CI to Gitea Actions' (#262) from feat/gitea-actions into main
authz_client / vulnerabilities (push) Successful in 1m58s
authz_client / test (push) Successful in 2m0s
Reviewed-on: https://gitea.unbound.se/shiny/authz_client/pulls/262
2026-01-08 17:59:17 +00:00
argoyle cd84a51f91 feat: migrate from GitLab CI to Gitea Actions
authz_client / test (pull_request) Successful in 1m14s
authz_client / vulnerabilities (pull_request) Successful in 1m23s
2026-01-08 18:33:57 +01:00
Unbound Release eab39dc818 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 524cad9180 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release b339804535 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release d2ed9ed12a chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release f521fb29c9 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 123dd2a4c2 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release c5943b41ec chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 5644b061c0 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 8330219579 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 425013f115 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 7f3b78b000 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release ab8a9809d5 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 9ef9084ffa chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release e48c5b3bb9 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 4421bcfbeb chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 18748ceaad chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 14d32b3b51 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release d571e92a0b chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release d355edd642 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release abd34b334a chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release da73907913 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release becde50685 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release a84a14a0d3 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 707e26b420 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release ffa2eca348 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 76fc782c96 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 4d3147c65c chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 6643990160 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 20d69f9c19 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release d327307539 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 5dce8a0f2b chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
Unbound Release 6f6272cb02 chore(release): prepare for v0.3.2 2025-12-31 21:12:27 +00:00
argoyle 7eddad8d4b Merge branch 'claude-docs' into 'main'
docs: add CLAUDE.md for Claude Code integration

See merge request unboundsoftware/shiny/authz_client!258
2025-12-31 22:10:52 +01:00
argoyle 1fd3ae5123 docs: add CLAUDE.md for Claude Code integration 2025-12-31 22:06:51 +01:00
argoyle 247c04a710 Merge branch 'renovate/golang-1.25.5' into 'main'
chore(deps): update golang:1.25.5 docker digest to ad03ba9

See merge request unboundsoftware/shiny/authz_client!257
2025-12-30 16:01:41 +01:00
Renovate 37f6c63025 chore(deps): update golang:1.25.5 docker digest to ad03ba9 2025-12-30 04:04:50 +00:00
argoyle 215a9ed976 Merge branch 'renovate/golang-1.25.5' into 'main'
chore(deps): update golang:1.25.5 docker digest to 0c27bcf

See merge request unboundsoftware/shiny/authz_client!256
2025-12-09 09:56:00 +01:00
Renovate 006ebd101e chore(deps): update golang:1.25.5 docker digest to 0c27bcf 2025-12-09 02:18:45 +00:00
argoyle 600653518c Merge branch 'renovate/golangci-golangci-lint-2.x' into 'main'
chore(deps): update pre-commit hook golangci/golangci-lint to v2.7.2

See merge request unboundsoftware/shiny/authz_client!255
2025-12-08 09:49:47 +01:00
Renovate c95cd1c80a chore(deps): update pre-commit hook golangci/golangci-lint to v2.7.2 2025-12-07 17:05:12 +00:00
argoyle 881a6f0e3c Merge branch 'renovate/golangci-golangci-lint-2.x' into 'main'
chore(deps): update pre-commit hook golangci/golangci-lint to v2.7.1

See merge request unboundsoftware/shiny/authz_client!254
2025-12-04 17:29:56 +01:00
Renovate 84939fa04b chore(deps): update pre-commit hook golangci/golangci-lint to v2.7.1 2025-12-04 15:07:58 +00:00
argoyle 0821cbb6eb Merge branch 'renovate/golangci-golangci-lint-2.x' into 'main'
chore(deps): update pre-commit hook golangci/golangci-lint to v2.7.0

See merge request unboundsoftware/shiny/authz_client!253
2025-12-04 08:31:19 +01:00
Renovate 0cb8363ab1 chore(deps): update pre-commit hook golangci/golangci-lint to v2.7.0 2025-12-03 20:05:00 +00:00
argoyle 8a440bd28c Merge branch 'renovate/golang-1.x' into 'main'
chore(deps): update golang docker tag to v1.25.5

See merge request unboundsoftware/shiny/authz_client!252
2025-12-02 20:15:25 +01:00
argoyle 13461b43e3 Merge branch 'renovate/go-1.x' into 'main'
chore(deps): update dependency go to v1.25.5

See merge request unboundsoftware/shiny/authz_client!251
2025-12-02 19:31:56 +01:00
Renovate 49100894e9 chore(deps): update golang docker tag to v1.25.5 2025-12-02 18:19:27 +00:00
Renovate 7818f97a7c chore(deps): update dependency go to v1.25.5 2025-12-02 17:17:24 +00:00
argoyle 66c429bde1 Merge branch 'renovate/gitleaks-gitleaks-8.x' into 'main'
chore(deps): update pre-commit hook gitleaks/gitleaks to v8.30.0

See merge request unboundsoftware/shiny/authz_client!250
2025-11-27 00:08:10 +01:00
Renovate 585fa5dfa4 chore(deps): update pre-commit hook gitleaks/gitleaks to v8.30.0 2025-11-26 19:06:23 +00:00
argoyle 82cca9b09c Merge branch 'renovate/gitleaks-gitleaks-8.x' into 'main'
chore(deps): update pre-commit hook gitleaks/gitleaks to v8.29.1

See merge request unboundsoftware/shiny/authz_client!249
2025-11-20 09:26:39 +01:00
Renovate bcbddac138 chore(deps): update pre-commit hook gitleaks/gitleaks to v8.29.1 2025-11-19 22:05:31 +00:00
argoyle e62257d933 Merge branch 'renovate/golang-1.25.4' into 'main'
chore(deps): update golang:1.25.4 docker digest to efe81fa

See merge request unboundsoftware/shiny/authz_client!248
2025-11-18 15:46:41 +01:00
Renovate f45918bac8 chore(deps): update golang:1.25.4 docker digest to efe81fa 2025-11-18 12:05:17 +00:00
argoyle 77ac58202a Merge branch 'renovate/golangci-golangci-lint-2.x' into 'main'
chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.2

See merge request unboundsoftware/shiny/authz_client!247
2025-11-14 16:25:46 +01:00
Renovate 257a97f191 chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.2 2025-11-14 14:06:05 +00:00
argoyle 32e8127273 Merge branch 'renovate/golang-1.x' into 'main'
chore(deps): update golang docker tag to v1.25.4

See merge request unboundsoftware/shiny/authz_client!246
2025-11-06 07:06:32 +01:00
Renovate 223f65396d chore(deps): update golang docker tag to v1.25.4 2025-11-05 22:18:16 +00:00
argoyle 01d4a4bc9f Merge branch 'renovate/go-1.x' into 'main'
chore(deps): update dependency go to v1.25.4

See merge request unboundsoftware/shiny/authz_client!245
2025-11-05 21:40:35 +01:00
Renovate 1038cff1d9 chore(deps): update dependency go to v1.25.4 2025-11-05 20:16:30 +00:00
argoyle f961bf91f7 Merge branch 'renovate/gitleaks-gitleaks-8.x' into 'main'
chore(deps): update pre-commit hook gitleaks/gitleaks to v8.29.0

See merge request unboundsoftware/shiny/authz_client!244
2025-11-05 08:34:23 +01:00
Renovate 721cb1be91 chore(deps): update pre-commit hook gitleaks/gitleaks to v8.29.0 2025-11-05 02:05:39 +00:00
argoyle 2f570a0638 Merge branch 'renovate/golangci-golangci-lint-2.x' into 'main'
chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.1

See merge request unboundsoftware/shiny/authz_client!243
2025-11-04 14:13:27 +01:00
argoyle ee52c50e76 Merge branch 'renovate/golang-1.25.3' into 'main'
chore(deps): update golang:1.25.3 docker digest to 9ac0edc

See merge request unboundsoftware/shiny/authz_client!242
2025-11-04 14:13:03 +01:00
Renovate 675ac0338f chore(deps): update pre-commit hook golangci/golangci-lint to v2.6.1 2025-11-04 12:07:17 +00:00
Renovate f708a18960 chore(deps): update golang:1.25.3 docker digest to 9ac0edc 2025-11-04 12:07:15 +00:00
argoyle a8ba5635e3 Merge branch 'test-concurrent-fetch-read-privileges' into 'main'
test: add concurrent fetch and read tests for privileges

See merge request unboundsoftware/shiny/authz_client!240
2025-11-03 12:46:01 +01:00
argoyle 4efc6572ee test: add concurrent fetch and read tests for privileges
Adds multiple tests to verify the thread-safety of the 
Fetch method and the handling of privileges in concurrent 
operations. Tests include concurrent fetching, reading 
privileges, and processing with multiple goroutines. 
Ensures no errors occur during operations and verifies 
privileges are set correctly.
2025-11-03 12:40:14 +01:00
18 changed files with 1560 additions and 254 deletions

No files matched your search

+81
View File
@@ -0,0 +1,81 @@
name: authz_client
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: 'stable'
- name: Run tests
run: go test -race -coverprofile=coverage.txt ./...
- name: Check coverage
id: coverage
run: |
go install github.com/vladopajic/go-test-coverage/v2@latest
go-test-coverage --config ./.testcoverage.yml --github-action-output
- name: Download baseline coverage
if: gitea.event_name == 'pull_request'
uses: actions/download-artifact@v3
with:
name: coverage-baseline
path: ./baseline
continue-on-error: true
- name: Compare coverage
if: gitea.event_name == 'pull_request'
run: |
CURRENT="${{ steps.coverage.outputs.total-coverage }}"
if [ -f ./baseline/coverage.txt ]; then
BASE=$(cat ./baseline/coverage.txt)
echo "Base coverage: ${BASE}%"
echo "Current coverage: ${CURRENT}%"
if [ "$(echo "$CURRENT < $BASE" | bc -l)" -eq 1 ]; then
echo "::error::Coverage decreased from ${BASE}% to ${CURRENT}%"
exit 1
fi
echo "Coverage maintained or improved: ${BASE}% -> ${CURRENT}%"
else
echo "No baseline coverage found, skipping comparison"
echo "Current coverage: ${CURRENT}%"
fi
- name: Save coverage baseline
if: gitea.ref == 'refs/heads/main'
run: echo "${{ steps.coverage.outputs.total-coverage }}" > coverage.txt
- name: Upload coverage baseline
if: gitea.ref == 'refs/heads/main'
uses: actions/upload-artifact@v3
with:
name: coverage-baseline
path: coverage.txt
retention-days: 90
- name: Post coverage comment
if: gitea.event_name == 'pull_request'
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_URL: ${{ gitea.server_url }}
run: |
COVERAGE="${{ steps.coverage.outputs.total-coverage }}"
curl -X POST "${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/issues/${{ gitea.event.pull_request.number }}/comments" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"body\": \"## Coverage Report\n\nTotal coverage: **${COVERAGE}%**\"}"
vulnerabilities:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: 'stable'
- name: Check vulnerabilities
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
+25
View File
@@ -0,0 +1,25 @@
name: pre-commit
permissions: read-all
on:
pull_request:
push:
branches:
- main
jobs:
pre-commit:
runs-on: ubuntu-latest
env:
SKIP: no-commit-to-branch
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: stable
- uses: actions/setup-python@v7
with:
python-version: '3.14'
- name: Install goimports
run: go install golang.org/x/tools/cmd/goimports@latest
- uses: pre-commit/action@v3.0.1
+9
View File
@@ -0,0 +1,9 @@
name: Release
on:
push:
branches: [main]
jobs:
release:
uses: unboundsoftware/shared-workflows/.gitea/workflows/Release.yml@main
+2
View File
@@ -1,2 +1,4 @@
.idea
.claude
/release
coverage.txt
-38
View File
@@ -1,38 +0,0 @@
include:
- template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
- project: unboundsoftware/ci-templates
file: Defaults.gitlab-ci.yml
- project: unboundsoftware/ci-templates
file: Release.gitlab-ci.yml
- project: unboundsoftware/ci-templates
file: Pre-Commit-Go.gitlab-ci.yml
image: amd64/golang:1.25.3@sha256:69d10098be2e990bb1d987daec0e36d18ad287e139450dc7d98a0ded3498888d
stages:
- deps
- test
deps:
stage: deps
script:
- go mod download
test:
stage: test
dependencies:
- deps
script:
- CGO_ENABLED=1 go test -mod=readonly -race -coverprofile=coverage.txt -covermode=atomic -coverpkg=$(go list ./... | tr '\n' , | sed 's/,$//') ./...
- go tool cover -html=coverage.txt -o coverage.html
- go tool cover -func=coverage.txt
- curl -Os https://uploader.codecov.io/latest/linux/codecov
- chmod +x codecov
- ./codecov -t ${CODECOV_TOKEN} -R $CI_PROJECT_DIR -C $CI_COMMIT_SHA -r $CI_PROJECT_PATH
vulnerabilities:
stage: test
image: amd64/golang:1.25.3@sha256:69d10098be2e990bb1d987daec0e36d18ad287e139450dc7d98a0ded3498888d
script:
- go install golang.org/x/vuln/cmd/govulncheck@latest
- govulncheck ./...
+4 -11
View File
@@ -10,15 +10,8 @@ repos:
args:
- --allow-multiple-documents
- id: check-added-large-files
- repo: https://gitlab.com/devopshq/gitlab-ci-linter
rev: v1.0.6
hooks:
- id: gitlab-ci-linter
args:
- --project
- unboundsoftware/shiny/authz_client
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
rev: v9.23.0
rev: v9.27.0
hooks:
- id: commitlint
stages: [ commit-msg ]
@@ -30,17 +23,17 @@ repos:
- id: go-imports
args:
- -local
- gitlab.com/unboundsoftware/shiny/authz_client
- gitea.unbound.se/shiny/authz_client
- repo: https://github.com/lietu/go-pre-commit
rev: v1.0.0
hooks:
- id: go-test
- id: gofumpt
- repo: https://github.com/golangci/golangci-lint
rev: v2.6.0
rev: v2.14.0
hooks:
- id: golangci-lint-full
- repo: https://github.com/gitleaks/gitleaks
rev: v8.28.0
rev: v8.30.1
hooks:
- id: gitleaks
+13
View File
@@ -0,0 +1,13 @@
# Coverage configuration for go-test-coverage
# https://github.com/vladopajic/go-test-coverage
profile: coverage.txt
threshold:
file: 0
package: 0
total: 0
exclude:
paths:
- _test\.go$
+3 -1
View File
@@ -1 +1,3 @@
{"version":"v0.3.1"}
{
"version": "v0.7.0"
}
+118
View File
@@ -2,6 +2,124 @@
All notable changes to this project will be documented in this file.
## [0.7.0] - 2026-09-16
### 🐛 Bug Fixes
- [**breaking**] Order privilege events by sequence number and merge snapshots by position (#333)
## [0.6.1] - 2026-09-16
### 🐛 Bug Fixes
- Keep existing privileges when User.Added is processed late (#331)
## [0.6.0] - 2026-09-14
### 🚀 Features
- [**breaking**] Consume privilege events with go-messaging-amqp (#327)
### ⚙️ Miscellaneous Tasks
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.2 (#325)
- Bump the minor version for breaking changes before 1.0.0 (#328)
## [0.5.1] - 2026-08-29
### 🐛 Bug Fixes
- *(ci)* Use go-test-coverage binary directly to fix Gitea Actions (#303)
- *(deps)* Update module github.com/stretchr/testify to v1.12.0 (#319)
- *(deps)* Update module github.com/stretchr/testify to v1.12.1 (#321)
### ⚙️ Miscellaneous Tasks
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.30.1 (#296)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.4 (#298)
- *(deps)* Update dependency go to v1.26.2 (#300)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.25.0 (#304)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.0 (#306)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.1 (#308)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.12.2 (#309)
- *(deps)* Update actions/checkout action to v7 (#311)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.26.0 (#313)
- *(deps)* Update actions/setup-go action to v7 (#315)
- *(deps)* Update actions/setup-python action to v7 (#317)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.13.1 (#322)
## [0.5.0] - 2026-03-12
### 🚀 Features
- *(client)* Add API key authentication for /authz endpoint (#294)
### ⚙️ Miscellaneous Tasks
- *(deps)* Update golang:1.25.5 docker digest to 3a01526 (#271)
- *(deps)* Update pre-commit hook alessandrojcm/commitlint-pre-commit-hook to v9.24.0 (#273)
- *(deps)* Update dependency go to v1.25.6 (#274)
- *(deps)* Update golang docker tag to v1.25.6 (#275)
- Remove GitLab CI configuration
- Add code coverage integration
- *(deps)* Update dependency go to v1.25.7 (#279)
- *(deps)* Update dependency go to v1.26.0 (#280)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.9.0 (#281)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.0 (#282)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.1 (#283)
- *(deps)* Update dependency go to v1.26.1 (#286)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.1 (#288)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.2 (#290)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.11.3 (#292)
## [0.4.1] - 2026-01-09
### ⚙️ Miscellaneous Tasks
- *(deps)* Update actions/setup-python action to v6
- Migrate module path to gitea.unbound.se
## [0.4.0] - 2026-01-09
### 🚀 Features
- Migrate from GitLab CI to Gitea Actions
### 🚜 Refactor
- Update module path to new repository location
### 📚 Documentation
- Add CLAUDE.md for Claude Code integration
### 🧪 Testing
- Add concurrent fetch and read tests for privileges
### ⚙️ Miscellaneous Tasks
- *(deps)* Update golang:1.25.3 docker digest to 9ac0edc
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.6.1
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.29.0
- *(deps)* Update dependency go to v1.25.4
- *(deps)* Update golang docker tag to v1.25.4
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.6.2
- *(deps)* Update golang:1.25.4 docker digest to efe81fa
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.29.1
- *(deps)* Update pre-commit hook gitleaks/gitleaks to v8.30.0
- *(deps)* Update dependency go to v1.25.5
- *(deps)* Update golang docker tag to v1.25.5
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.7.0
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.7.1
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.7.2
- *(deps)* Update golang:1.25.5 docker digest to 0c27bcf
- *(deps)* Update golang:1.25.5 docker digest to ad03ba9
- *(deps)* Update actions/setup-go action to v6
- *(deps)* Update actions/checkout action to v6
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.8.0
- Add pre-commit and release workflows
## [0.3.1] - 2025-11-02
### 🐛 Bug Fixes
+51
View File
@@ -0,0 +1,51 @@
# authz_client
Shared Go library for authorization service client integration.
## Shared Documentation
@../docs/claude/architecture.md
@../docs/claude/go-services.md
@../docs/claude/conventions.md
## Library Information
### Purpose
Provides a client for the authz-service, handling privilege management for users across companies. Used by all microservices that need to check user permissions.
### Usage
```go
import client "gitea.unbound.se/shiny/authz_client"
// Create handler with options
handler := client.New(client.WithBaseURL("http://authz-service"))
// Check user privileges
allowed := handler.IsAllowed(email, companyID, func(p client.CompanyPrivileges) bool {
return p.Invoicing
})
```
### Privileges
The `CompanyPrivileges` struct contains permission flags:
- `Admin` - Administrative access
- `Company` - Company management
- `Consumer` - Consumer/customer access
- `Time` - Time tracking
- `Invoicing` - Invoice management
- `Accounting` - Accounting access
- `Supplier` - Supplier management
- `Salary` - Salary/payroll access
### Event Handling
Registers per-replica (transient) go-messaging-amqp consumers for privilege events from authz-service (`Setup()`). Each routing key gets its own queue, so events arrive in any order. `Process` orders them by the `sequenceNo` authz-service's event store stamps on every event: all four events come from authz-service's `Company` aggregate, so the global sequence number orders them within a company. Each (email, company) keeps the sequence number of the last fact about membership and about each privilege; an event only overrides older facts. `User.Removed` stamps every privilege, so a late grant can't come back. An event without `sequenceNo` fails closed: additions are dropped, and removals apply and block every later event for those facts until the next snapshot. An event with a negative or implausibly large `sequenceNo` is dropped. Tests that seed the handler must set `SequenceNo`.
### Startup
Call `Fetch()` **after** `conn.Start` (consumers bound), never before: events published between the snapshot and the binding would otherwise be lost. authz-service only serves a snapshot whose read view has applied every stored event. It sends that position in the `X-Authz-Sequence` header and answers 503 while the read view lags (backlog, backfill, reset); `Fetch` retries 503 for about a minute. `Fetch` merges the snapshot as facts at that sequence number (newer event facts win, pairs missing from the snapshot are removed) and drops later events at or below it. A snapshot older than one already merged is ignored, so concurrent or repeated fetches are safe. A snapshot without the header merges at 0 and logs a warning (rollout window only). When the `/authz` contract changes, deploy authz-service before the services that use this library.
Don't combine `Setup()` with go-messaging-amqp's `WithReconnect`: a reconnect declares new per-replica queues, so revocations published during the outage are lost unless `Fetch()` runs again. Services exit on connection loss (`CloseListener`) and re-fetch on start.
-3
View File
@@ -1,4 +1 @@
# Shiny authz-client
[![Build Status](https://gitlab.com/unboundsoftware/shiny/authz_client/badges/main/pipeline.svg)](https://gitlab.com/unboundsoftware/shiny/authz_client/commits/main)
[![codecov](https://codecov.io/gl/unboundsoftware:shiny/authz_client/branch/main/graph/badge.svg?token=AQS7QVLCEQ)](https://codecov.io/gl/unboundsoftware:shiny/authz_client)
+320 -80
View File
@@ -1,16 +1,31 @@
package client
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log/slog"
"math"
"net/http"
"reflect"
"strconv"
"sync"
"time"
"github.com/sparetimecoders/goamqp"
goamqp "codeberg.org/messaging/go-messaging-amqp"
spec "codeberg.org/messaging/messaging"
)
// SequenceHeader carries the global sequence number of the authz-service read view the
// /authz snapshot was read at.
const SequenceHeader = "X-Authz-Sequence"
// pending marks a fact cleared by an event without a sequence number. No event can
// override it; only a snapshot can.
const pending = math.MaxInt
// CompanyPrivileges contains the privileges for a combination of email address and company id
type CompanyPrivileges struct {
Admin bool `json:"admin"`
@@ -23,12 +38,84 @@ type CompanyPrivileges struct {
Salary bool `json:"salary"`
}
// field returns the flag for privilege, or nil for an unknown privilege.
func (c *CompanyPrivileges) field(privilege Privilege) *bool {
switch privilege {
case PrivilegeAdmin:
return &c.Admin
case PrivilegeCompany:
return &c.Company
case PrivilegeConsumer:
return &c.Consumer
case PrivilegeTime:
return &c.Time
case PrivilegeInvoicing:
return &c.Invoicing
case PrivilegeAccounting:
return &c.Accounting
case PrivilegeSupplier:
return &c.Supplier
case PrivilegeSalary:
return &c.Salary
}
return nil
}
// companyState is what the handler knows about one email in one company. Every
// privilege event for a company comes from authz-service's Company aggregate, so
// its global sequence number orders the events for the pair. The four routing
// keys arrive on separate queues in any order; a fact is only overwritten by a
// fact with a higher sequence number.
type companyState struct {
privileges CompanyPrivileges
// privilegeSeq is the sequence number of the last fact about each privilege.
privilegeSeq map[Privilege]int
// member is whether the user belongs to the company, as of memberSeq. A
// User.Removed stamps every privilege with its sequence number, so a grant
// older than the removal can't come back.
member bool
memberSeq int
}
func newCompanyState() *companyState {
return &companyState{privilegeSeq: map[Privilege]int{}}
}
// clearPending turns facts cleared without a sequence number into unordered facts, so
// the snapshot being merged replaces them.
func (s *companyState) clearPending() {
if s.memberSeq == pending {
s.memberSeq = 0
}
for p, seq := range s.privilegeSeq {
if seq == pending {
s.privilegeSeq[p] = 0
}
}
}
// maxSeq is the highest sequence number of any fact in the state.
func (s *companyState) maxSeq() int {
m := s.memberSeq
for _, seq := range s.privilegeSeq {
m = max(m, seq)
}
return m
}
// PrivilegeHandler processes PrivilegeAdded-events and fetches the initial set of privileges from an authz-service
type PrivilegeHandler struct {
*sync.RWMutex
client *http.Client
baseURL string
privileges map[string]map[string]*CompanyPrivileges
client *http.Client
baseURL string
apiKey string
state map[string]map[string]*companyState
// floor is the sequence number of the newest snapshot. Its effects are all in
// the state, so an event at or below it is stale.
floor int
// retries is how many times Fetch retries a snapshot authz-service isn't ready to serve.
retries int
retryDelay time.Duration
}
// OptsFunc is used to configure the PrivilegeHandler
@@ -41,13 +128,22 @@ func WithBaseURL(url string) OptsFunc {
}
}
// WithAPIKey sets an API key used as a Bearer token when fetching privileges
func WithAPIKey(key string) OptsFunc {
return func(handler *PrivilegeHandler) {
handler.apiKey = key
}
}
// New creates a new PrivilegeHandler. Pass OptsFuncs to configure.
func New(opts ...OptsFunc) *PrivilegeHandler {
handler := &PrivilegeHandler{
RWMutex: &sync.RWMutex{},
client: &http.Client{},
client: &http.Client{Timeout: 30 * time.Second},
baseURL: "http://authz-service",
privileges: map[string]map[string]*CompanyPrivileges{},
state: map[string]map[string]*companyState{},
retries: 60,
retryDelay: time.Second,
}
for _, opt := range opts {
opt(handler)
@@ -55,101 +151,250 @@ func New(opts ...OptsFunc) *PrivilegeHandler {
return handler
}
// Fetch the initial set of privileges from an authz-service
// Fetch a snapshot of all privileges from an authz-service and merge it into the state.
//
// Call it after the AMQP connection has started: authz-service only serves a snapshot
// that includes every stored event, so together with the bound queues no event is
// missed. While its read view is behind it answers 503, and Fetch retries. The snapshot
// is applied as facts at its sequence number: a fact from an event newer than the
// snapshot is kept, everything else is replaced, and a pair missing from the snapshot is
// removed. A snapshot older than one already merged is ignored.
func (h *PrivilegeHandler) Fetch() error {
resp, err := h.client.Get(fmt.Sprintf("%s/authz", h.baseURL))
for attempt := 0; ; attempt++ {
err := h.fetch()
if !errors.Is(err, errNotReady) || attempt >= h.retries {
return err
}
time.Sleep(h.retryDelay)
}
}
var errNotReady = errors.New("fetch privileges: authz-service read view not ready")
func (h *PrivilegeHandler) fetch() error {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/authz", h.baseURL), nil)
if err != nil {
return err
}
if h.apiKey != "" {
req.Header.Set("Authorization", "Bearer "+h.apiKey)
}
resp, err := h.client.Do(req)
if err != nil {
return err
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode == http.StatusServiceUnavailable {
return errNotReady
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("fetch privileges: unexpected status %s", resp.Status)
}
buff, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
h.Lock()
defer h.Unlock()
err = json.Unmarshal(buff, &h.privileges)
if err != nil {
var snapshot map[string]map[string]CompanyPrivileges
if err := json.Unmarshal(buff, &snapshot); err != nil {
return err
}
seq := 0
if v := resp.Header.Get(SequenceHeader); v != "" {
seq, err = strconv.Atoi(v)
if err != nil || seq < 0 {
return fmt.Errorf("fetch privileges: invalid %s header %q", SequenceHeader, v)
}
} else {
// ponytail: only during the rollout window, before authz-service sends the header.
slog.Warn("authz snapshot has no sequence number; events older than it can revert it", "header", SequenceHeader)
}
h.Lock()
defer h.Unlock()
h.merge(snapshot, seq)
return nil
}
func (h *PrivilegeHandler) merge(snapshot map[string]map[string]CompanyPrivileges, seq int) {
if seq < h.floor {
// A newer snapshot is already merged; this one could only bring back removed state.
slog.Warn("ignoring authz snapshot older than the one already merged", "seq", seq, "floor", h.floor)
return
}
for email, companies := range h.state {
for companyID, s := range companies {
s.clearPending()
if _, exists := snapshot[email][companyID]; exists {
continue
}
if s.maxSeq() <= seq {
// Nothing newer than the snapshot; the floor keeps stale events out.
delete(companies, companyID)
continue
}
removeUser(s, seq, false)
}
if len(companies) == 0 {
delete(h.state, email)
}
}
for email, companies := range snapshot {
for companyID, privileges := range companies {
s := h.company(email, companyID)
if s.memberSeq <= seq {
s.member = true
s.memberSeq = seq
}
for _, p := range AllPrivilege {
if s.privilegeSeq[p] <= seq {
*s.privileges.field(p) = *privileges.field(p)
s.privilegeSeq[p] = seq
}
}
}
}
h.floor = max(h.floor, seq)
}
func (h *PrivilegeHandler) Setup() []goamqp.Setup {
return []goamqp.Setup{
goamqp.TransientEventStreamConsumer("User.Added", h.Process, UserAdded{}),
goamqp.TransientEventStreamConsumer("User.Removed", h.Process, UserRemoved{}),
goamqp.TransientEventStreamConsumer("Privilege.Added", h.Process, PrivilegeAdded{}),
goamqp.TransientEventStreamConsumer("Privilege.Removed", h.Process, PrivilegeRemoved{}),
goamqp.TransientEventStreamConsumer("User.Added", process[UserAdded](h)),
goamqp.TransientEventStreamConsumer("User.Removed", process[UserRemoved](h)),
goamqp.TransientEventStreamConsumer("Privilege.Added", process[PrivilegeAdded](h)),
goamqp.TransientEventStreamConsumer("Privilege.Removed", process[PrivilegeRemoved](h)),
}
}
// Process privilege-related events and update the internal state
func (h *PrivilegeHandler) Process(msg interface{}, _ goamqp.Headers) (interface{}, error) {
// privilegeEvent is the set of events Process handles.
type privilegeEvent interface {
UserAdded | UserRemoved | PrivilegeAdded | PrivilegeRemoved
}
// process adapts Process to a typed go-messaging-amqp handler.
func process[T privilegeEvent](h *PrivilegeHandler) spec.EventHandler[T] {
return func(_ context.Context, event spec.ConsumableEvent[T]) error {
return h.Process(&event.Payload)
}
}
// Process privilege-related events and update the internal state.
//
// Events are applied by sequence number, not by arrival order. An event without a
// sequence number can't be ordered, so it fails closed: a removal is applied and an
// addition is dropped.
func (h *PrivilegeHandler) Process(msg any) error {
h.Lock()
defer h.Unlock()
switch ev := msg.(type) {
case *UserAdded:
if priv, exists := h.privileges[ev.Email]; exists {
priv[ev.CompanyID] = &CompanyPrivileges{}
} else {
h.Lock()
defer h.Unlock()
h.privileges[ev.Email] = map[string]*CompanyPrivileges{
ev.CompanyID: {},
}
if h.stale(ev.SequenceNo, true, ev) {
return nil
}
return nil, nil
s := h.company(ev.Email, ev.CompanyID)
if ev.SequenceNo > s.memberSeq {
s.member = true
s.memberSeq = ev.SequenceNo
}
return nil
case *UserRemoved:
if priv, exists := h.privileges[ev.Email]; exists {
h.Lock()
defer h.Unlock()
delete(priv, ev.CompanyID)
if h.stale(ev.SequenceNo, false, ev) {
return nil
}
return nil, nil
removeUser(h.company(ev.Email, ev.CompanyID), ev.SequenceNo, ev.SequenceNo == 0)
return nil
case *PrivilegeAdded:
h.Lock()
defer h.Unlock()
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, true)
return nil, nil
if h.stale(ev.SequenceNo, true, ev) {
return nil
}
h.setPrivilege(ev.Email, ev.CompanyID, ev.Privilege, ev.SequenceNo, true)
return nil
case *PrivilegeRemoved:
h.Lock()
defer h.Unlock()
h.setPrivileges(ev.Email, ev.CompanyID, ev.Privilege, false)
return nil, nil
if h.stale(ev.SequenceNo, false, ev) {
return nil
}
h.setPrivilege(ev.Email, ev.CompanyID, ev.Privilege, ev.SequenceNo, false)
return nil
default:
fmt.Printf("Got unexpected message type (%s): '%+v'\n", reflect.TypeOf(msg).String(), msg)
return nil, fmt.Errorf("unexpected event type: '%s'", reflect.TypeOf(msg))
slog.Error("unexpected privilege message type", "type", reflect.TypeOf(msg).String())
return fmt.Errorf("unexpected event type: '%s'", reflect.TypeOf(msg))
}
}
func (h *PrivilegeHandler) setPrivileges(email, companyId string, privilege Privilege, set bool) {
if priv, exists := h.privileges[email]; exists {
if c, exists := priv[companyId]; exists {
switch privilege {
case PrivilegeAdmin:
c.Admin = set
case PrivilegeCompany:
c.Company = set
case PrivilegeConsumer:
c.Consumer = set
case PrivilegeTime:
c.Time = set
case PrivilegeInvoicing:
c.Invoicing = set
case PrivilegeAccounting:
c.Accounting = set
case PrivilegeSupplier:
c.Supplier = set
case PrivilegeSalary:
c.Salary = set
}
} else {
priv[companyId] = &CompanyPrivileges{}
h.setPrivileges(email, companyId, privilege, set)
// stale reports whether an event must be skipped: an addition without a sequence
// number, or any event already covered by the latest snapshot.
func (h *PrivilegeHandler) stale(seq int, addition bool, ev any) bool {
if seq < 0 || seq >= pending {
slog.Error("dropping privilege event with invalid sequence number", "type", reflect.TypeOf(ev).String(), "seq", seq)
return true
}
if seq == 0 {
if addition {
slog.Warn("dropping privilege addition without sequence number", "type", reflect.TypeOf(ev).String())
}
} else {
h.privileges[email] = map[string]*CompanyPrivileges{}
h.setPrivileges(email, companyId, privilege, set)
return addition
}
return seq <= h.floor
}
func (h *PrivilegeHandler) company(email, companyID string) *companyState {
companies, exists := h.state[email]
if !exists {
companies = map[string]*companyState{}
h.state[email] = companies
}
s, exists := companies[companyID]
if !exists {
s = newCompanyState()
companies[companyID] = s
}
return s
}
// removeUser removes the user at seq, overriding every fact older than seq. An
// unordered removal (all) overrides every fact and marks them pending, so no event can
// bring them back before the next snapshot.
func removeUser(s *companyState, seq int, all bool) {
stamp := seq
if all {
stamp = pending
}
if all || s.memberSeq < seq {
s.member = false
s.memberSeq = max(s.memberSeq, stamp)
}
for _, p := range AllPrivilege {
if all || s.privilegeSeq[p] < seq {
*s.privileges.field(p) = false
s.privilegeSeq[p] = max(s.privilegeSeq[p], stamp)
}
}
}
func (h *PrivilegeHandler) setPrivilege(email, companyID string, privilege Privilege, seq int, set bool) {
if !privilege.IsValid() {
return
}
s := h.company(email, companyID)
if seq != 0 && seq <= s.privilegeSeq[privilege] {
return
}
*s.privileges.field(privilege) = set
if seq == 0 {
// Only an unordered removal gets here; keep it until the next snapshot.
seq = pending
}
s.privilegeSeq[privilege] = max(s.privilegeSeq[privilege], seq)
// authz-service's aggregate adds the user when a privilege is granted.
if set && seq > s.memberSeq {
s.member = true
s.memberSeq = seq
}
}
@@ -157,12 +402,10 @@ func (h *PrivilegeHandler) setPrivileges(email, companyId string, privilege Priv
func (h *PrivilegeHandler) CompaniesByUser(email string, predicate func(privileges CompanyPrivileges) bool) []string {
h.RLock()
defer h.RUnlock()
var result []string
if p, exists := h.privileges[email]; exists {
for k, v := range p {
if predicate(*v) {
result = append(result, k)
}
result := []string{}
for k, s := range h.state[email] {
if s.member && predicate(s.privileges) {
result = append(result, k)
}
}
return result
@@ -172,11 +415,8 @@ func (h *PrivilegeHandler) CompaniesByUser(email string, predicate func(privileg
func (h *PrivilegeHandler) IsAllowed(email, companyID string, predicate func(privileges CompanyPrivileges) bool) bool {
h.RLock()
defer h.RUnlock()
if p, exists := h.privileges[email]; exists {
if v, exists := p[companyID]; exists {
return predicate(*v)
}
if s, exists := h.state[email][companyID]; exists && s.member {
return predicate(s.privileges)
}
return false
}
+814 -84
View File
File diff suppressed because it is too large. Load diff
+4
View File
@@ -78,3 +78,7 @@ filter_commits = false
topo_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "oldest"
[bump]
# Before 1.0.0, a breaking change bumps the minor version instead of the major.
breaking_always_bump_major = false
+16 -11
View File
@@ -1,15 +1,18 @@
package client
// UserAdded is the event sent when a new user is added to a company
// UserAdded is the event sent when a new user is added to a company.
// SequenceNo is authz-service's global event sequence number; it orders the events.
type UserAdded struct {
Email string `json:"email"`
CompanyID string `json:"companyId"`
Email string `json:"email"`
CompanyID string `json:"companyId"`
SequenceNo int `json:"sequenceNo"`
}
// UserRemoved is the event sent when a user is removed from a company
type UserRemoved struct {
Email string `json:"email"`
CompanyID string `json:"companyId"`
Email string `json:"email"`
CompanyID string `json:"companyId"`
SequenceNo int `json:"sequenceNo"`
}
// Privilege is an enumeration of all available privileges
@@ -51,14 +54,16 @@ func (e Privilege) String() string {
// PrivilegeAdded is the event sent when a new privilege is added
type PrivilegeAdded struct {
Email string `json:"email"`
CompanyID string `json:"companyId"`
Privilege Privilege `json:"privilege"`
Email string `json:"email"`
CompanyID string `json:"companyId"`
Privilege Privilege `json:"privilege"`
SequenceNo int `json:"sequenceNo"`
}
// PrivilegeRemoved is the event sent when a privilege is removed
type PrivilegeRemoved struct {
Email string `json:"email"`
CompanyID string `json:"companyId"`
Privilege Privilege `json:"privilege"`
Email string `json:"email"`
CompanyID string `json:"companyId"`
Privilege Privilege `json:"privilege"`
SequenceNo int `json:"sequenceNo"`
}
+23 -11
View File
@@ -1,19 +1,31 @@
module gitlab.com/unboundsoftware/shiny/authz_client
module gitea.unbound.se/shiny/authz_client
go 1.22.12
toolchain go1.25.3
go 1.26.2
require (
github.com/sparetimecoders/goamqp v0.3.3
github.com/stretchr/testify v1.11.1
codeberg.org/messaging/go-messaging-amqp v0.0.6
codeberg.org/messaging/messaging v0.0.5
github.com/stretchr/testify v1.12.1
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rabbitmq/amqp091-go v1.15.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel v1.44.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/sys v0.45.0 // indirect
google.golang.org/protobuf v1.36.8 // indirect
)
+67 -15
View File
@@ -1,20 +1,72 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
codeberg.org/messaging/go-messaging-amqp v0.0.6 h1:TAPcIspjjg44MNXwbcscW+ol1kIX49lnX2N3dsh0e0s=
codeberg.org/messaging/go-messaging-amqp v0.0.6/go.mod h1:R4Hg1w964P7OP7vQ9AsXdd4KjgN/YlQ/9+XzXKpEVp4=
codeberg.org/messaging/messaging v0.0.5 h1:/ueH90F4RNPUeeJIwdG9oVhDW7+XjCzwOYq8xc0kfQk=
codeberg.org/messaging/messaging v0.0.5/go.mod h1:xyWLUcfaVzcN6GWk9uaQsxPVUC2Vm2S89mYZGdiWTWg=
codeberg.org/messaging/messaging/tck v0.0.3 h1:a4Nr7ytFqEJloTOyVeAtMNgO9Fig1ZUirjW4FVlK0lc=
codeberg.org/messaging/messaging/tck v0.0.3/go.mod h1:RiOsKXGAhNQK2STBVYGjhN0CFtmcrsEne1qUe15n8Q4=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/sparetimecoders/goamqp v0.3.3 h1:z/nfTPmrjeU/rIVuNOgsVLCimp3WFoNFvS3ZzXRJ6HE=
github.com/sparetimecoders/goamqp v0.3.3/go.mod h1:W9NRCpWLE+Vruv2dcRSbszNil2O826d2Nv6kAkETW5o=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
github.com/nats-io/nats.go v1.52.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/rabbitmq/amqp091-go v1.15.0 h1:LEQL4/yp48/Wigt6A6XOu18RQRo8ZHtB5I/KZJn+gkw=
github.com/rabbitmq/amqp091-go v1.15.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+10
View File
@@ -2,5 +2,15 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"packageRules": [
{
"groupName": "OpenTelemetry",
"matchPackageNames": [
"go.opentelemetry.io/**",
"gitea.unbound.se/shiny/otelsetup",
"gitea.unbound.se/shiny/logging"
]
}
]
}