Skip to content

feat(ext): support authenticated principals and config - #657

Open
SantiagoDePolonia wants to merge 11 commits into
mainfrom
feat/extension-auth-principals
Open

feat(ext): support authenticated principals and config#657
SantiagoDePolonia wants to merge 11 commits into
mainfrom
feat/extension-auth-principals

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add strict extension-owned config and provider-neutral request authenticators
  • preserve stable principal IDs and normalized authentication methods in SQL and Mongo audit entries
  • expose provider-neutral browser login, logout, and current-user discovery headers for the dashboard
  • persist sanitized extension authentication lifecycle events through the existing audit pipeline
  • treat usable extension authenticators as effective authentication in startup safety reporting
  • redact authentication credentials and transaction values from access-log URIs and audited Location headers without adding allocations to query-free model traffic

SSO and OIDC remain entirely in Pro; Core only provides protocol-neutral extension seams, UI discovery, durable audit integration, and generic sensitive-query redaction.

Validation

  • GOWORK=off go test ./...
  • golangci-lint run
  • full repository pre-commit suite: race tests, dashboard tests and dist sync, performance guard, fix-check, and lint
  • real AWS Cognito browser E2E through Pro: login, PKCE, stable principal, durable audit, local and provider logout, group denial, safe callback failure, transaction replay rejection, and log/audit redaction
  • temporary Cognito environment deleted after verification

Summary by CodeRabbit

  • New Features
    • Added extension-provided authentication, including SSO login, logout, identity details, and dashboard access controls.
    • Added configurable extension sections and startup configuration hooks.
    • Added authenticated external-user details and logout controls to the dashboard.
  • Bug Fixes
    • Improved audit records with authentication methods, principal IDs, event details, and extension authentication events.
    • Redacted sensitive credentials from logged URLs and request data.
    • Preserved explicit bearer/API-key authentication precedence over extension authentication.
    • Improved handling of missing, invalid, or unavailable authentication metadata.

Copilot AI lite review requested due to automatic review settings August 6, 2026 22:07

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a407c4cb-1cf6-4aff-9c73-0dfe231cd2d7

📥 Commits

Reviewing files that changed from the base of the PR and between 8e3383c and 2e82412.

⛔ Files ignored due to path filters (2)
  • internal/admin/dashboard/static/dist/assets/index-DbvfJbHk.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/index.html is excluded by !**/dist/**
📒 Files selected for processing (8)
  • ext/auth.go
  • ext/auth_test.go
  • internal/app/app.go
  • internal/app/lifecycle_test.go
  • internal/server/auth.go
  • internal/server/auth_test.go
  • web/dashboard/src/lib/stores/external-auth.js
  • web/dashboard/tests/external-auth.test.js

📝 Walkthrough

Walkthrough

The change adds opaque extension configuration, one-time setup, pluggable request authenticators, authentication context propagation, audit persistence, credential URL redaction, and dashboard support for external authentication.

Changes

Extension configuration and setup

Layer / File(s) Summary
Opaque configuration and setup callback
config/config.go, config/config.example.yaml, config/config_test.go, run/run.go, run/run_test.go
Extension YAML sections are preserved and strictly decoded by extensions. SetupConfig runs once after configuration loading and propagates setup errors.

Authenticator API and wiring

Layer / File(s) Summary
Authenticator contracts, registry, and application wiring
ext/auth.go, ext/registry.go, ext/*_test.go, internal/app/app.go, internal/app/app_test.go, internal/app/lifecycle_test.go
The extension API defines authentication identities, context helpers, event recording, and concurrency-safe authenticator registration. The application copies usable authenticators into server configuration and binds compatible event recorders.

Request authentication

Layer / File(s) Summary
Authentication middleware and access control
internal/server/auth.go, internal/server/http.go, internal/server/auth_test.go, internal/server/admin_access_test.go
Explicit credentials retain priority. Configured request authenticators run when explicit credentials are absent. Valid identities populate request context, permissions, snapshots, and audit metadata.

Principal ID audit persistence

Layer / File(s) Summary
Audit enrichment, events, and storage
internal/auditlog/*
Audit entries accept normalized authentication methods, principal IDs, and event types. Authentication events become durable audit entries. SQL and MongoDB storage persists, indexes, reads, and streams the new fields.

Credential redaction and dashboard metadata

Layer / File(s) Summary
Redaction and external-authentication UI
internal/core/url_redaction.go, internal/server/request_log.go, internal/server/request_log_test.go, web/dashboard/src/lib/*, web/dashboard/tests/external-auth.test.js
Server request logging and audit headers redact sensitive query values. Dashboard responses expose sanitized external login, logout, and user metadata, which the login dialog and sidebar render.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Request
  participant AuthMiddlewareWithRequestAuthenticators
  participant RequestAuthenticator
  participant AuthenticationContext
  participant AuthenticationEventRecorder
  participant AuditLogStore
  Request->>AuthMiddlewareWithRequestAuthenticators: Request without explicit credentials
  AuthMiddlewareWithRequestAuthenticators->>RequestAuthenticator: AuthenticateRequest(request)
  RequestAuthenticator-->>AuthMiddlewareWithRequestAuthenticators: Authentication
  AuthMiddlewareWithRequestAuthenticators->>AuthenticationContext: WithAuthentication(authentication)
  AuthenticationContext->>AuthenticationEventRecorder: Authentication event metadata
  AuthenticationEventRecorder->>AuditLogStore: Durable audit entry
  AuditLogStore-->>Request: Authenticated request continues
Loading

Possibly related PRs

Poem

A rabbit checks the config nest,
Then sends auth through every test.
IDs cross the audit trail,
Hidden query secrets fail.
Login links and users show,
Safe external paths now glow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes for extension authentication and configuration.
Description check ✅ Passed The description explains the changes, scope, rationale, and validation results, although it uses Summary instead of the template's Description heading.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/extension-auth-principals

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/config.example.yaml`:
- Around line 540-545: Update the commented extensions configuration example to
explicitly state that extensions is absent by default and operators should add
an extension section only when required by their custom distribution, while
preserving the existing explanation of extension-owned validation.

In `@internal/auditlog/enrich.go`:
- Line 308: Make authentication-method handling provider-neutral: in
internal/auditlog/enrich.go lines 308-308, accept and validate opaque extension
methods without enumerating the SSO-specific value; in
internal/auditlog/auditlog.go lines 39-39, remove the SSO-specific Core constant
or replace it with a generic extension-auth method, ensuring other extension
providers remain supported.

In `@internal/auditlog/middleware.go`:
- Around line 211-213: Update applyAuthentication to trim
authentication.PrincipalID and assign it to entry.PrincipalID only when the
trimmed value is non-empty, preserving any previously populated ID; add a
regression test covering an existing ID with an empty or whitespace-only context
principal.

In `@internal/auditlog/store_sql_test.go`:
- Around line 62-78: Update the round-trip test around the direct audit_logs
query to call SQLReader.GetLogs and inspect the returned log entry, asserting
PrincipalID along with the existing relevant fields. Retain only any direct
database checks needed for writer persistence, ensuring the test exercises
scanSQLLogEntry’s positional column contract.

In `@internal/server/auth_test.go`:
- Around line 264-316: Extend the auth middleware tests around
AuthMiddlewareWithRequestAuthenticators with table-driven cases covering
authenticator errors, nil results, multiple authenticators, empty PrincipalID,
invalid UserPath, and an extension identity lacking DashboardAccess on an admin
route. Assert the expected status and response behavior for each case, including
that error responses do not expose extension error text, while preserving the
existing success and explicit master-key precedence coverage.

In `@internal/server/auth.go`:
- Around line 146-148: Update AdminAccessMiddleware’s dashboard-access denial
response for extension identities to use an identity-neutral message such as
“identity does not have dashboard access” instead of referring specifically to
an API key, while preserving the existing authorization behavior.
- Around line 117-142: The applyExtensionAuthResult function currently
normalizes identity fields only locally while storing the original result in
context. Trim result.PrincipalID and copy result before setting its PrincipalID
and normalized UserPath, then pass that copy to ext.WithAuthentication; use the
normalized principal value for the corresponding audit enrichment as well.
- Around line 98-100: The AuthenticateRequest error path in the request handler
exposes raw extension errors through authenticationErrorWithAudit; replace
authFailureMessage(err) with the fixed public message "authentication failed"
and retain only a sanitized error code in the audit data. Ensure API keys,
authorization headers, secrets, and upstream diagnostics are not returned or
logged.

In `@internal/server/http.go`:
- Around line 353-355: Update the authSkipPaths construction in
internal/server/http.go so "/admin/*" is added only when cfg.MasterKey is empty
and no RequestAuthenticators are configured; keep extension-authenticated admin
requests flowing through AuthMiddlewareWithRequestAuthenticators. Add an
integration test covering an extension identity with DashboardAccess: false and
verify admin REST access is denied unless a master key or authorized managed key
is present.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 55e5e61f-9cce-4463-8170-7fed2b9b60d7

📥 Commits

Reviewing files that changed from the base of the PR and between 225a3fb and e5de74c.

📒 Files selected for processing (23)
  • config/config.example.yaml
  • config/config.go
  • config/config_test.go
  • ext/auth.go
  • ext/registry.go
  • ext/registry_test.go
  • internal/app/app.go
  • internal/app/app_test.go
  • internal/auditlog/auditlog.go
  • internal/auditlog/enrich.go
  • internal/auditlog/middleware.go
  • internal/auditlog/middleware_test.go
  • internal/auditlog/reader_mongodb.go
  • internal/auditlog/reader_sql.go
  • internal/auditlog/store_mongodb.go
  • internal/auditlog/store_sql.go
  • internal/auditlog/store_sql_test.go
  • internal/auditlog/stream_wrapper.go
  • internal/server/auth.go
  • internal/server/auth_test.go
  • internal/server/http.go
  • run/run.go
  • run/run_test.go

Comment thread config/config.example.yaml Outdated
Comment thread internal/auditlog/enrich.go Outdated
Comment thread internal/auditlog/middleware.go
Comment thread internal/auditlog/store_sql_test.go Outdated
Comment thread internal/server/auth_test.go
Comment thread internal/server/auth.go Outdated
Comment thread internal/server/auth.go Outdated
Comment thread internal/server/auth.go
Comment thread internal/server/http.go Outdated
@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

Confidence Score: 3/5

Not safe to merge until explicit credential authentication removes any pre-existing extension identity from the request context.

A reproduced security-sensitive authorization-boundary failure remains in explicit credential handling.

Files Needing Attention: internal/server/auth.go

Security Review

A request that supplies a valid explicit credential can still expose an identity installed earlier by extension middleware. Downstream authorization, tenant-scoping, or label consumers may therefore act on the ambient extension principal instead of the credential that authenticated the request.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced proofs for two posted P1 findings.
  • Authentication-related tests were executed, with three passing and one failing.
  • General contract validation confirmed oidc persistence passed in both the existing middleware test and the authored direct test, while the authored ambient boundary test failed because ambient identity was still returned after master-key authentication.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 Explicit Authorization authentication retains ambient extension identity

    • Bug
      • When an outer extension middleware has already stored an OIDC identity in the request context, a valid Authorization: Bearer master request reaches the downstream handler with that extension identity still present. The response user header is cleared, but context consumers can still observe oidc:ambient.
    • Cause
      • internal/server/auth.go:67-79 clears only X-GoModel-Auth-User via setAuthenticationUserHeader(c, ""); it does not remove or replace the ext.Authentication value already attached to c.Request().Context().
    • Fix
      • At the explicit-credential boundary, rebuild the request context without the ambient extension authentication (or make extension identity lookup explicitly credential-precedence-aware), then set that request back on the Echo context before calling the selected credential authenticator/handler.

    T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "fix(dashboard): avoid new credential sto..." | Re-trigger Greptile

Comment thread internal/server/auth.go Outdated
Copilot AI review requested due to automatic review settings August 6, 2026 22:59

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Addressed the review audit in c95ccaf:

  • closed the extension-authenticated admin bypass while preserving the no-auth recovery mode
  • sanitized extension failures in both responses and audit data
  • made auth methods provider-neutral with bounded identifiers and a generic fallback
  • normalized identity data before storing it in context
  • preserved existing principal IDs when late context enrichment is blank
  • exercised SQL reader persistence and all request-authenticator failure/fallthrough paths
  • clarified the default extension configuration state

Validation: go test ./...; go test -race ./config ./ext ./internal/auditlog ./internal/server; all repository pre-commit hooks passed. The docstring warning was reviewed separately: all new exported APIs and the non-obvious normalization helper are documented; adding comments to every private test/helper solely to satisfy the heuristic would add noise.

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/server/auth.go (1)

41-41: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle nil request authenticators consistently.

A slice containing only nil authenticators has a non-zero length. The request loop skips those values. The current checks then register authentication, disable admin recovery, and reject requests with missing credentials although no authenticator can authenticate them.

  • internal/server/auth.go#L41-L41: determine whether at least one non-nil request authenticator exists before disabling the no-authentication path.
  • internal/server/http.go#L247-L247: use the same non-nil check before disabling the admin recovery bypass.
  • internal/server/http.go#L353-L355: use the same non-nil check before registering authentication middleware.
Proposed fix
+func hasRequestAuthenticator(authenticators []ext.RequestAuthenticator) bool {
+	for _, authenticator := range authenticators {
+		if authenticator != nil {
+			return true
+		}
+	}
+	return false
+}

Replace each len(...RequestAuthenticators) == 0 or > 0 presence check with this helper. Add a regression test for []ext.RequestAuthenticator{nil}.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/server/auth.go` at line 41, Replace request-authenticator length
checks with a shared non-nil presence check so slices containing only nil
authenticators are treated as having no usable authenticator. Update the checks
at internal/server/auth.go:41, internal/server/http.go:247, and
internal/server/http.go:353-355, preserving the existing no-authentication,
admin-recovery, and middleware behavior for genuinely usable authenticators. Add
a regression test covering []ext.RequestAuthenticator{nil}.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/server/auth.go`:
- Line 41: Replace request-authenticator length checks with a shared non-nil
presence check so slices containing only nil authenticators are treated as
having no usable authenticator. Update the checks at internal/server/auth.go:41,
internal/server/http.go:247, and internal/server/http.go:353-355, preserving the
existing no-authentication, admin-recovery, and middleware behavior for
genuinely usable authenticators. Add a regression test covering
[]ext.RequestAuthenticator{nil}.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 01da5c17-f22e-4d26-ad46-599118bbfc3b

📥 Commits

Reviewing files that changed from the base of the PR and between e5de74c and c95ccaf.

📒 Files selected for processing (12)
  • config/config.example.yaml
  • ext/auth.go
  • internal/auditlog/auditlog.go
  • internal/auditlog/enrich.go
  • internal/auditlog/middleware.go
  • internal/auditlog/middleware_auth_method_test.go
  • internal/auditlog/middleware_test.go
  • internal/auditlog/store_sql_test.go
  • internal/server/admin_access_test.go
  • internal/server/auth.go
  • internal/server/auth_test.go
  • internal/server/http.go

Copilot AI review requested due to automatic review settings August 6, 2026 23:04

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Incremental CodeRabbit finding addressed in 63a59af: request-authenticator presence now ignores both nil interfaces and typed-nil implementations consistently in the no-auth path, admin recovery decision, middleware registration, and request loop. Added middleware and full admin-server regression tests for both nil forms. Pro remains green without a local workspace against the refreshed Core pin.

@codecov-commenter

codecov-commenter commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 78.24675% with 67 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/core/url_redaction.go 0.00% 34 Missing ⚠️
internal/server/auth.go 89.89% 6 Missing and 4 partials ⚠️
internal/app/app.go 76.47% 7 Missing and 1 partial ⚠️
internal/auditlog/authentication_events.go 81.81% 4 Missing and 4 partials ⚠️
config/config.go 86.66% 1 Missing and 1 partial ⚠️
ext/registry.go 80.00% 2 Missing ⚠️
internal/auditlog/store_mongodb.go 0.00% 2 Missing ⚠️
run/run.go 80.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copilot AI review requested due to automatic review settings August 7, 2026 09:00

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Codecov patch-coverage feedback addressed in 55f9a3e with behavioral tests for the meaningful uncovered paths: public authentication context round trips and defensive reads, principal-ID enrichment, and absent extension configuration. Local package coverage moved from 0% to 100% for ext/auth.go, from 0% to 100% for EnrichEntryWithPrincipalID, and DecodeExtension from 78.6% to 92.9%. Full tests and every pre-commit hook pass. The separate Codecov App installation warning is repository/organization configuration rather than a code change.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

The completed upload is now reflected in the Codecov API: patch coverage is 91.43% (160 hits, 11 misses, 4 partials), up from 78.86%. The older bot comment remains stale because this repository is using tokenless uploads without the Codecov App; its own warning notes that comments may not be reliably updated.

Copilot AI review requested due to automatic review settings August 7, 2026 11:28

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 7, 2026 12:23

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/dashboard/src/lib/api/client.js (1)

31-39: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not apply metadata from stale responses.

Line 34 updates external authentication state before the generation check. If the API key changes while a request is in flight, an older response can replace the current login URL, logout URL, or displayed user. Compute stale before observing the response and skip observation when it is stale.

Proposed fix
 async function request(path, options, { label = path, parse = true } = {}) {
   const generation = auth.generation;
   const res = await apiFetch(path, options);
-  auth.observeResponse(res);
+  const stale = generation < auth.generation;
+  if (!stale) {
+    auth.observeResponse(res);
+  }
   if (res.status === 401) {
     auth.handleUnauthorized(generation);
     return { ok: false, stale: generation < auth.generation, status: 401, data: null, res };
   }
-  const stale = generation < auth.generation;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/dashboard/src/lib/api/client.js` around lines 31 - 39, Update request so
it computes the stale flag immediately after apiFetch and before
auth.observeResponse. Only call auth.observeResponse(res) when the response is
not stale, while preserving the existing 401 handling and stale response
metadata.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/auditlog/authentication_events.go`:
- Around line 67-75: Sanitize the path before storing it in the LogEntry
construction by applying core.RedactSensitiveURLQuery to the trimmed event.Path
value. Update the relevant authentication event test to cover a callback URI
containing sensitive query parameters such as code, state, or id_token and
verify the stored Path contains redacted values.

In `@web/dashboard/src/lib/components/organisms/Sidebar.svelte`:
- Around line 111-126: Update the conditional in the Sidebar external-auth
section to render whenever auth.externalLogoutURL is available, and make the
external-auth-user row conditional on auth.externalUser. Keep the logout link
and its gomodelPath(auth.externalLogoutURL) behavior unchanged.

---

Outside diff comments:
In `@web/dashboard/src/lib/api/client.js`:
- Around line 31-39: Update request so it computes the stale flag immediately
after apiFetch and before auth.observeResponse. Only call
auth.observeResponse(res) when the response is not stale, while preserving the
existing 401 handling and stale response metadata.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4c99fb0b-54b0-4aad-a0e6-17f34d23f9ce

📥 Commits

Reviewing files that changed from the base of the PR and between 55f9a3e and 0fd8284.

⛔ Files ignored due to path filters (5)
  • internal/admin/dashboard/static/dist/assets/index-BFUCi3g4.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/assets/index-CT5lg2co.css is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/assets/index-Cz8GQupq.css is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/assets/index-nQCIlv1m.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/index.html is excluded by !**/dist/**
📒 Files selected for processing (18)
  • ext/auth.go
  • internal/app/app.go
  • internal/app/app_test.go
  • internal/auditlog/auditlog.go
  • internal/auditlog/auditlog_test.go
  • internal/auditlog/authentication_events.go
  • internal/auditlog/authentication_events_test.go
  • internal/auditlog/stream_wrapper.go
  • internal/core/url_redaction.go
  • internal/server/http.go
  • internal/server/request_log.go
  • internal/server/request_log_test.go
  • web/dashboard/src/lib/api/client.js
  • web/dashboard/src/lib/components/organisms/AuthDialog.svelte
  • web/dashboard/src/lib/components/organisms/Sidebar.svelte
  • web/dashboard/src/lib/stores/auth.svelte.js
  • web/dashboard/src/lib/stores/external-auth.js
  • web/dashboard/tests/external-auth.test.js

Comment thread internal/auditlog/authentication_events.go
Comment thread web/dashboard/src/lib/components/organisms/Sidebar.svelte Outdated
…rincipals

# Conflicts:
#	internal/admin/dashboard/static/dist/assets/index-_N2yDOD9.css
#	internal/admin/dashboard/static/dist/index.html
Copilot AI review requested due to automatic review settings August 7, 2026 12:50

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Merged latest main in d3cc163 and addressed all findings from the latest review. In addition to the two inline fixes, stale API responses can no longer overwrite external login, logout, or user metadata from a newer authentication generation. Rebuilt the embedded dashboard bundle. Validation: full Go suite, 474 dashboard tests, Svelte check, production dashboard build, repository pre-commit race suite, performance guard, fix-check, and lint.

Copilot AI review requested due to automatic review settings August 7, 2026 13:53

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread web/dashboard/src/lib/stores/api-key-storage.js Fixed
Copilot AI review requested due to automatic review settings August 7, 2026 14:02

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 7, 2026 14:07

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Final SSO hardening update:

  • dad297c7: Core now reports the authentication identity it actually selected; explicit bearer/API-key credentials clear any outer SSO-advertised user, while managed keys and request authenticators publish their effective user path. The dashboard clears the existing persisted API key synchronously before following SSO.
  • b0c148b5: manual SSO selection now carries the current dashboard path and query, matching automatic SSO redirects.
  • 8e3383c1: addressed the new CodeQL review without suppression by removing the newly introduced credential-storage abstraction; the pre-existing persistence behavior remains unchanged and SSO still removes the stored key. Dashboard dist rebuilt each time.

Validation: full go test ./..., dashboard unit tests, Svelte checks, production build/dist sync, targeted lint, repository pre-commit hooks, plus real AWS Cognito browser E2E through a temporary HTTPS reverse proxy. The browser test covered an intentionally stale bearer key, manual SSO return to /admin/dashboard/usage?window=7d, automatic SSO return to /admin/dashboard/audit-logs?user=Alice, PKCE, effective-user display, authenticated API loading, and provider logout. Temporary infrastructure was deleted. All review threads are resolved.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Post-review verification: reran the deployed Cognito browser regression against the final Core head 8e3383c1 (not the earlier helper implementation). An invalid persisted bearer key was cleared by manual SSO selection, the callback returned exactly to /admin/dashboard/usage?window=7d, authenticated APIs loaded, and the effective SSO user rendered. Automatic SSO separately returned exactly to /admin/dashboard/audit-logs?user=Alice. Provider logout passed. The second Cognito pool, tunnel, server, and temporary databases were deleted.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/server/auth.go`:
- Around line 66-71: Update the explicit-credential branch in
AuthMiddlewareWithRequestAuthenticators to reset
ext.AuthenticationFromContext(c.Request().Context()) to a cleared identity, and
clear or override the inherited core.UserPathFromContext context value before
master-key or managed-key validation continues downstream. Keep the existing
setAuthenticationUserHeader call while ensuring all inherited authentication
context is removed.

In `@web/dashboard/src/lib/stores/external-auth.js`:
- Around line 18-21: Update the login URL construction around returnTo so any
fragment in loginURL is separated before adding the return_to query parameter,
then reattach the unchanged fragment after the query string. Preserve existing
query-separator and encoding behavior, and add a regression test covering
/g/sso/login#fragment.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 114ee09a-5c80-4d23-ab92-135389e6c452

📥 Commits

Reviewing files that changed from the base of the PR and between 0fd8284 and 8e3383c.

⛔ Files ignored due to path filters (3)
  • internal/admin/dashboard/static/dist/assets/index-DM1VKejK.css is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/assets/index-nqGolcSX.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/index.html is excluded by !**/dist/**
📒 Files selected for processing (10)
  • internal/auditlog/authentication_events.go
  • internal/auditlog/authentication_events_test.go
  • internal/server/auth.go
  • internal/server/auth_test.go
  • web/dashboard/src/lib/api/client.js
  • web/dashboard/src/lib/components/organisms/AuthDialog.svelte
  • web/dashboard/src/lib/components/organisms/Sidebar.svelte
  • web/dashboard/src/lib/stores/auth.svelte.js
  • web/dashboard/src/lib/stores/external-auth.js
  • web/dashboard/tests/external-auth.test.js

Comment thread internal/server/auth.go
Comment thread web/dashboard/src/lib/stores/external-auth.js Outdated
Comment thread internal/server/auth.go
@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Review follow-up in 2e82412: recorder rebinding now occurs only after the replacement App has completed every fallible construction step; a late-failure lifecycle regression proves the old recorder is unchanged. Explicit credentials now mask both inherited extension authentication and its effective user-path override before Core validates the selected credential. External login deep links insert return_to before URL fragments, with query/fragment regression coverage. The dashboard production bundle was rebuilt. Validation: go test ./..., focused race tests, golangci-lint, 476 dashboard tests, Svelte checks, production build, and all pre-commit hooks.

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.

4 participants