Skip to content

refactor(storage)!: decouple storage from authn via a Principal/Extractor interface - #158

Draft
sthanikan2000 wants to merge 1 commit into
mainfrom
refactor/storage-decouple-authn
Draft

refactor(storage)!: decouple storage from authn via a Principal/Extractor interface#158
sthanikan2000 wants to merge 1 commit into
mainfrom
refactor/storage-decouple-authn

Conversation

@sthanikan2000

Copy link
Copy Markdown
Collaborator

Summary

  • storage only ever used authn.GetAuthContext as a bare "is there an authenticated caller" nil-check — no role/scope/claim access. It now defines its own minimal Principal{ Subject() string } interface and Extractor func type, mirroring the authz.Principal/Extractor pattern already established in this repo. *authn.AuthContext satisfies Principal structurally, so callers bridge it in at their composition root without storage importing authn at all.
  • NewHTTPHandler now takes an Extractor and returns (*HTTPHandler, error), failing closed on a nil extractor (same convention as authz.New).
  • storage/README.md documents the new wiring with an authn example.
  • Root go.mod/go.sum no longer need authn (or its transitive golang-jwt/jwt/v5 dep) at all, since storage was the only consumer in this repo.

This is a breaking change for NewHTTPHandler callers (new required parameter, new error return) — see storage/README.md for the migration example.

Follow-up (separate PR, not in this change): extract storage into its own Go module now that it no longer needs authn as a dependency, following the same playbook used for authz/pagination/trace/etc.

Test plan

  • go build ./storage/... / go vet ./storage/...
  • go test ./storage/... -v — all pass
  • go build ./... / go test ./... at repo root — all pass
  • golangci-lint run ./storage/... — 0 issues
  • grep -rn authn storage/ — only a doc comment and the README example remain, no Go import
  • Pre-commit/pre-push hooks (gitleaks, license headers, lint, go mod tidy check, race tests) all passed locally

…ctor interface

storage only ever used authn.GetAuthContext as a bare "is there an
authenticated caller" nil-check, never touching roles/scopes/claims. Mirror
the authz.Principal/Extractor pattern already established in this repo:
storage now defines its own minimal Principal{ Subject() string } interface
and Extractor func type, which *authn.AuthContext satisfies structurally
without storage importing that package.

NewHTTPHandler now takes an Extractor and returns (*HTTPHandler, error),
failing closed on a nil extractor (same convention as authz.New). Callers
bridge their auth library in at the composition root — see storage/README.md
for an authn example.

With storage decoupled, authn was the root module's only path to
golang-jwt/jwt/v5; `go mod tidy` drops both from go.mod/go.sum.

This also clears the way for a follow-up extracting storage into its own
Go module, since it no longer needs authn as a dependency at all.
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a1568980-5df1-4e02-a035-0a5b1d3d62a2


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sthanikan2000

Copy link
Copy Markdown
Collaborator Author

Resequencing this behind #159: we're extracting `storage` into its own Go module first (non-breaking, releases as `storage/v0.1.0`) so downstream repos can pick up the module split without any code changes. This PR's `authn` → `Principal`/`Extractor` change is a real breaking API change, so it'll follow as a separate release (e.g. `v0.2.0`) once #159 has merged and been tagged — giving downstream repos time to migrate the two changes independently.

Marking as draft until #159 lands; will rebase this branch onto the resulting `main` (which will include `storage/go.mod`) before marking ready again.

sthanikan2000 added a commit that referenced this pull request Aug 23, 2026
storage is the last remaining candidate matching the pattern already used
for authn, authz, shared, remote, secret, database, payment, pagination,
trace, and uiprojector: give it its own go.mod so it can be versioned and
released independently of the root module.

No source changes — storage keeps its current authn dependency for now, so
this is purely a module-boundary change. Existing importers of
github.com/OpenNSW/core/storage need to add an explicit
`require github.com/OpenNSW/core/storage vX.Y.Z` to their own go.mod, but no
code changes are needed on their end.

Adds a storage-module CI job (mirroring authn-module) and lists /storage in
dependabot.yml. Root's go.mod/go.sum drop authn and its transitive
golang-jwt/jwt/v5 dependency, since storage was the only in-repo consumer
and it now carries that requirement itself.

Deliberately sequenced before the authn-decoupling change (#158): this lets
storage ship as a non-breaking v0.1.0 first, so downstream repos can pick up
the independent module before separately opting into the breaking
Principal/Extractor interface change later.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
sthanikan2000 added a commit that referenced this pull request Aug 23, 2026
storage is the last remaining candidate matching the pattern already used
for authn, authz, shared, remote, secret, database, payment, pagination,
trace, and uiprojector: give it its own go.mod so it can be versioned and
released independently of the root module.

No source changes — storage keeps its current authn dependency for now, so
this is purely a module-boundary change. Existing importers of
github.com/OpenNSW/core/storage need to add an explicit
`require github.com/OpenNSW/core/storage vX.Y.Z` to their own go.mod, but no
code changes are needed on their end.

Adds a storage-module CI job (mirroring authn-module) and lists /storage in
dependabot.yml. Root's go.mod/go.sum drop authn and its transitive
golang-jwt/jwt/v5 dependency, since storage was the only in-repo consumer
and it now carries that requirement itself.

Deliberately sequenced before the authn-decoupling change (#158): this lets
storage ship as a non-breaking v0.1.0 first, so downstream repos can pick up
the independent module before separately opting into the breaking
Principal/Extractor interface change later.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
sthanikan2000 added a commit that referenced this pull request Aug 23, 2026
storage is the last remaining candidate matching the pattern already used
for authn, authz, shared, remote, secret, database, payment, pagination,
trace, and uiprojector: give it its own go.mod so it can be versioned and
released independently of the root module.

No source changes — storage keeps its current authn dependency for now, so
this is purely a module-boundary change. Existing importers of
github.com/OpenNSW/core/storage need to add an explicit
`require github.com/OpenNSW/core/storage vX.Y.Z` to their own go.mod, but no
code changes are needed on their end.

Adds a storage-module CI job (mirroring authn-module) and lists /storage in
dependabot.yml. Root's go.mod/go.sum drop authn and its transitive
golang-jwt/jwt/v5 dependency, since storage was the only in-repo consumer
and it now carries that requirement itself.

Deliberately sequenced before the authn-decoupling change (#158): this lets
storage ship as a non-breaking v0.1.0 first, so downstream repos can pick up
the independent module before separately opting into the breaking
Principal/Extractor interface change later.
@sthanikan2000 sthanikan2000 self-assigned this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant