Skip to content

Add RFC 9396 Rich Authorization Requests support - #171

Merged
goshacodes merged 6 commits into
mainfrom
feat/rar-authorization-details
Aug 15, 2026
Merged

Add RFC 9396 Rich Authorization Requests support#171
goshacodes merged 6 commits into
mainfrom
feat/rar-authorization-details

Conversation

@goshacodes

Copy link
Copy Markdown
Member

Summary

Implements RFC 9396 (Rich Authorization Requests) end to end:

  • central: register/update/delete authorization detail types per tenant, each backed by a JSON Schema (2020-12). Synced to auth via the existing polling ReloadingCache pattern; Postgres NOTIFY-based cache invalidation on the central side (authorization_detail_type_change).
  • auth: parses and validates authorization_details on /authorize and /par (RFC 9126 integration). Rejects unknown types and schema violations. resource://edge is supported as a location, validated the same way as the resource parameter (and rejected when mixed with internal resources).
  • persistence: authorization_details stored as a nullable column across conversation, authorization code, and refresh token records/repositories, so an absent parameter (NULL) is distinguishable from an explicit empty request.
  • JsonSchemaValidator: compiled schemas are cached by canonical schema text, bounded to avoid unbounded growth from repeated schema edits (an edit produces a new cache key rather than replacing the old one). Lookups are lock-free (ConcurrentHashMap); the size bound is enforced only on the miss path (schema registration/edit), which keeps the hot validate() path free of locking.
  • central-ui: management screens for authorization detail types.
  • e2e: happy path, unregistered-type rejection, and invalid-schema-registration rejection, including through the PAR flow.

Testing

  • Full test suite: 1467 passing, 0 failing.
  • e2e: 32/32 passing against freshly restarted central + auth (Postgres-backed).

Notes

  • authorization_details columns are nullable with no default, to distinguish "no details requested" from "empty details requested".
  • Schema validation happens twice: validateSchema (meta-schema structural check) at registration time, and validate (compile + validate) lazily on first use at authorize/PAR time, with the result cached thereafter.

Pull Request opened by Augment Code | View session

- Central: register/update/delete authorization detail types per tenant,
  each backed by a JSON Schema (2020-12); synced to auth via the existing
  polling ReloadingCache pattern, with Postgres NOTIFY-based cache
  invalidation on the central side.
- Auth: parse and validate authorization_details on /authorize and /par
  (RFC 9126 integration) against the registered schema; reject unknown
  types and schema violations. Support resource://edge locations,
  validated the same way as the resource parameter.
- Persist authorization_details as a nullable column across conversation,
  authorization code, and refresh token records/repositories, so an
  absent parameter (NULL) is distinguishable from an empty request.
- JsonSchemaValidator: cache compiled schemas by canonical schema text,
  bounded to avoid unbounded growth from repeated schema edits; lookups
  use a lock-free ConcurrentHashMap, with the bound enforced only on the
  miss path.
- central-ui: management screens for authorization detail types.
- e2e: happy path, unregistered type, and invalid schema registration
  coverage, including the PAR flow.
versola-navigation's :host was position: fixed with height: 100vh. That
keeps it correctly pinned to the viewport during real scrolling, but caps
its own height at one viewport regardless of the document's actual
height. A tool that captures the whole scrollable page in one shot (full
page screenshot, print/PDF) then renders one viewport's worth of sidebar
followed by flat background for the rest of a taller document \u2014 visible
on any screen whose content pushes the page past the fold, e.g.
resources' "Add endpoint" panel.

Split the sizing and pinning responsibilities instead: :host is now a
plain flex sizer stretched to the row's full height by admin-app's
.app-layout (now display: flex), while the actual viewport-pinned panel
is an inner .nav-panel (position: sticky, height: 100vh). The mobile
off-canvas drawer, which is genuinely meant to be exactly one viewport
tall, keeps the previous fixed-positioning approach on :host directly.

Verified via Playwright: sidebar sizer now spans the full document
height on a tall resources form, nav content still stays pinned during
real-viewport scrolling, and the mobile drawer still opens/closes
off-canvas without shifting main content width. Full existing suite:
106/108 passing (the 2 failures reproduce identically on unmodified
main, unrelated to this change).
…n-details

# Conflicts:
#	auth/implementations/postgres/src/main/scala/versola/oauth/conversation/PostgresConversationRepository.scala
#	auth/src/main/scala/versola/oauth/authorize/AuthorizeRequestParser.scala
#	auth/src/main/scala/versola/oauth/authorize/model/AuthorizeRequest.scala
#	auth/src/main/scala/versola/oauth/conversation/model/ConversationRecord.scala
#	auth/src/main/scala/versola/oauth/token/OAuthTokenService.scala
#	auth/src/test/scala/versola/oauth/token/OAuthTokenServiceSpec.scala
#	central/src/main/scala/versola/central/configuration/dto.scala
#	e2e/src/test/scala/versola/e2e/support/OAuthClient.scala
@goshacodes
goshacodes marked this pull request as ready for review August 15, 2026 15:19
@goshacodes

Copy link
Copy Markdown
Member Author

augment review

@augmentcode

augmentcode Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor
🤖 Augment PR Summary

Summary: Adds end-to-end RFC 9396 Rich Authorization Requests support.

Changes:

  • Adds tenant-scoped authorization-detail type registration, JSON Schema validation, storage, sync, and cache invalidation.
  • Parses and validates authorization_details at authorization and PAR endpoints, including location/resource checks.
  • Persists granted details through conversations, authorization codes, refresh tokens, JWTs, token responses, and introspection.
  • Adds refresh-token and client-credentials handling for requested authorization details.
  • Publishes supported types in server metadata and adds Central UI management screens.
  • Introduces a bounded compiled JSON Schema cache and related unit, repository, and E2E coverage.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

@goshacodes
goshacodes merged commit fe8e8b2 into main Aug 15, 2026
6 checks passed
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