Skip to content

feat: use session token for API auth#361

Merged
agaffney merged 1 commit into
mainfrom
feat/api-session-token
Jul 1, 2026
Merged

feat: use session token for API auth#361
agaffney merged 1 commit into
mainfrom
feat/api-session-token

Conversation

@agaffney

@agaffney agaffney commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary by cubic

Switch API auth to short‑lived Bearer session tokens signed with one global Ed25519 JWT key. Adds POST /api/auth/session and requires Bearer tokens on WireGuard and Client Profile routes; enforces wallet ownership and subscription expiry.

  • New Features

    • POST /api/auth/session exchanges a wallet‑signed "vpn-session:<unix>" COSE challenge for a 30‑minute session JWT; wallet must own at least one subscription; returns expires_at.
    • Session JWTs: Ed25519, aud="session", iat/exp required, sub=<wallet credential hex>; peer tokens are rejected as sessions.
    • Unified auth extracts Bearer and authorizes body client_id against the token’s wallet credential; Client Profile and WG devices/peer delete also reject expired subscriptions; consistent 401 vs 500 auth errors.
    • Swagger adds BearerAuth and marks protected routes; request models drop signature/key. A single issuer from VPN_JWT_KEY_FILE is required at startup and also authenticates the indexer to the WireGuard container; /api/auth/session is always available.
  • Migration

    • Set VPN_JWT_KEY_FILE (remove VPN_WG_JWT_KEY_FILE).
    • Get a token: POST /api/auth/session with a COSE signature over "vpn-session:<unix>" and the public key.
    • Use it by sending Authorization: Bearer <token> to WireGuard and Client Profile endpoints; include client_id. Remove signature and key from requests.

Written for commit 7ad6d1f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added POST /api/auth/session to exchange a wallet-signed challenge for short-lived session tokens.
    • Enabled bearer session-token authorization across protected API and WireGuard endpoints.
  • Bug Fixes
    • Switched WireGuard/API auth flow to use session-token verification (no legacy COSE signature/key checks).
    • Added fail-fast validation for missing session JWT issuer and aligned subscription-expiry enforcement with authenticated requests.
  • Documentation
    • Updated Swagger docs and request/response schemas to reflect session-based Bearer auth and removed legacy signature/key fields.
  • Tests
    • Expanded session-JWT tests and updated WireGuard request parsing tests.

@agaffney
agaffney requested a review from a team as a code owner June 26, 2026 18:42
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds session JWT issuance and verification in the JWT issuer, passes the issuer into API startup, registers /api/auth/session, and updates API authentication to use bearer session tokens. WireGuard and client profile request handling were updated to use the shared authentication path, and the Swagger docs and tests were revised accordingly.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: switching API authentication to session tokens.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/api-session-token

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

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/api/wireguard_test.go (1)

93-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add handler-level coverage for the deferred-auth contract.

This test now allows {} at unmarshal time, so please add cases proving {} without a bearer token is rejected and a bearer-token request succeeds without COSE fields.

🤖 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/api/wireguard_test.go` around lines 93 - 98, The WireGuard test
suite now accepts an empty JSON object in parsing, so add handler-level coverage
in wireguard_test.go to verify the deferred-auth behavior. Update the relevant
tests around the existing empty object case in the handler path so that a
request with {} and no Bearer token is rejected, and a request with a Bearer
session token succeeds even when COSE signature/key fields are omitted. Use the
existing handler/auth test helpers and the WireGuard request handling flow to
place these assertions near the current unmarshal cases.
🤖 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/api/wireguard.go`:
- Around line 793-795: The delete and device-list handlers in wgDevicesImpl
currently call a.authenticate but discard the returned client, so they skip the
subscription-expiry check used elsewhere. Update those paths to follow the same
pattern as register/profile by keeping the authenticated client, checking
tmpClient.Expiration, and rejecting expired subscriptions before continuing. Use
the existing a.authenticate, tmpClient, and wgDevicesImpl flow so the expiry
gate is enforced consistently for both operations.

In `@internal/jwt/issuer.go`:
- Around line 132-140: Require the session token to include an expiration claim
in VerifySessionJWT by adding the appropriate jwt.Parse option alongside the
existing audience and valid-method checks. Update the token validation in
Issuer.VerifySessionJWT so tokens without exp are rejected, keeping the current
signing key and sessionAudience enforcement intact.

---

Nitpick comments:
In `@internal/api/wireguard_test.go`:
- Around line 93-98: The WireGuard test suite now accepts an empty JSON object
in parsing, so add handler-level coverage in wireguard_test.go to verify the
deferred-auth behavior. Update the relevant tests around the existing empty
object case in the handler path so that a request with {} and no Bearer token is
rejected, and a request with a Bearer session token succeeds even when COSE
signature/key fields are omitted. Use the existing handler/auth test helpers and
the WireGuard request handling flow to place these assertions near the current
unmarshal cases.
🪄 Autofix (Beta)

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: CHILL

Plan: Pro

Run ID: 6ebe1a71-c118-43cf-b885-c49d08f7b346

📥 Commits

Reviewing files that changed from the base of the PR and between 152925f and 6f48255.

📒 Files selected for processing (7)
  • cmd/vpn-indexer/main.go
  • internal/api/api.go
  • internal/api/auth.go
  • internal/api/wireguard.go
  • internal/api/wireguard_test.go
  • internal/jwt/issuer.go
  • internal/jwt/issuer_test.go

Comment thread internal/api/wireguard.go Outdated
Comment thread internal/jwt/issuer.go

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

6 issues found across 7 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/api/wireguard.go Outdated
Comment thread internal/jwt/issuer.go
Comment thread internal/jwt/issuer_test.go
Comment thread internal/api/auth.go Outdated
Comment thread internal/jwt/issuer.go Outdated
Comment thread internal/api/auth.go Outdated
@agaffney
agaffney force-pushed the feat/api-session-token branch 2 times, most recently from 37cb57c to ce711f9 Compare June 26, 2026 19:32
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review this please

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

@agaffney Reviewing Pull Request #361 now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@agaffney
agaffney force-pushed the feat/api-session-token branch 3 times, most recently from e09c99d to 155e7d0 Compare June 26, 2026 20:34
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review this again

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

@agaffney Re-running a full review of #361 now.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
cmd/vpn-indexer/main.go (1)

160-187: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Initialize the session JWT issuer outside the WireGuard-only branch.

In "openvpn" mode, jwtIssuer remains nil, so api.Start(..., jwtIssuer) causes /api/auth/session to be skipped by internal/api/api.go. That makes the new session-token flow unavailable for OpenVPN despite the API auth code documenting the token as protocol-neutral.

Possible direction
  var wgClient *wireguard.Client
  var s3Client *client.Client
  var jwtIssuer *jwt.Issuer
+
+ // Initialize JWT issuer for browser session tokens, and reuse it for
+ // WireGuard container authentication when WireGuard is enabled.
+ jwtIssuer, err = jwt.NewIssuer(cfg.Vpn.WGJWTKeyFile)
+ if err != nil {
+ 	slog.Error(
+ 		fmt.Sprintf("failed to initialize JWT issuer: %s", err),
+ 	)
+ 	os.Exit(1)
+ }

  switch cfg.Vpn.Protocol {
...
-		// Initialize JWT issuer for WG container authentication
-		// and browser session tokens
-		jwtIssuer, err = jwt.NewIssuer(cfg.Vpn.WGJWTKeyFile)
-		if err != nil {
-			slog.Error(
-				fmt.Sprintf("failed to initialize JWT issuer: %s", err),
-			)
-			os.Exit(1)
-		}

Also applies to: 257-257

🤖 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 `@cmd/vpn-indexer/main.go` around lines 160 - 187, The session JWT issuer is
only initialized inside the WireGuard branch, leaving jwtIssuer nil in openvpn
mode and causing api.Start to skip the session-auth route. Move the
jwt.NewIssuer initialization out of the protocol-specific switch in main, and
ensure both openvpn and wireguard paths pass a valid jwtIssuer into api.Start so
/api/auth/session is available regardless of protocol.
🤖 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/api/auth.go`:
- Around line 323-329: The session token response in SessionResponse is returned
without cache-prevention headers, so add a Cache-Control header with no-store
before writing the JSON in this handler. Update the response setup near the
existing Content-Type header and json.Marshal/write logic so bearer token
responses are explicitly marked non-cacheable.

In `@internal/api/client.go`:
- Around line 206-207: Authenticate COSE requests before any profile existence
check in the non-token path. In the flow around client.New and the ProfileExists
lookup, move the !viaToken signature/key verification block ahead of any DB/S3
access, and ensure a missing id is rejected before calling into profile lookup
logic. Keep the auth-first ordering consistent across the referenced request
handling paths so unauthenticated callers cannot infer whether a profile exists
from differing responses.
- Around line 293-296: The Ed25519 key hashing path in client.go can panic
because vkey.(ed25519.PublicKey) is used without verifying the type first.
Update the code around the vkeyHash computation to use an “ok” type assertion
check like the patterns in auth.go and wireguard.go, and if the key is not an
ed25519.PublicKey, return a 400-style error instead of proceeding to hash it.

---

Outside diff comments:
In `@cmd/vpn-indexer/main.go`:
- Around line 160-187: The session JWT issuer is only initialized inside the
WireGuard branch, leaving jwtIssuer nil in openvpn mode and causing api.Start to
skip the session-auth route. Move the jwt.NewIssuer initialization out of the
protocol-specific switch in main, and ensure both openvpn and wireguard paths
pass a valid jwtIssuer into api.Start so /api/auth/session is available
regardless of protocol.
🪄 Autofix (Beta)

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: CHILL

Plan: Pro

Run ID: cb4bffd5-1297-4bd4-ba2e-0c08a29407df

📥 Commits

Reviewing files that changed from the base of the PR and between 152925f and 155e7d0.

📒 Files selected for processing (8)
  • cmd/vpn-indexer/main.go
  • internal/api/api.go
  • internal/api/auth.go
  • internal/api/client.go
  • internal/api/wireguard.go
  • internal/api/wireguard_test.go
  • internal/jwt/issuer.go
  • internal/jwt/issuer_test.go

Comment thread internal/api/auth.go
Comment thread internal/api/client.go Outdated
Comment thread internal/api/client.go Outdated
@agaffney
agaffney force-pushed the feat/api-session-token branch 3 times, most recently from 64125bd to db1ab22 Compare June 26, 2026 21:13
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review this

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

@agaffney Reviewing #361 now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@wolf31o2 wolf31o2 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NO-GO for merge as-is. Local verification: go test ./... and git diff --check origin/main...pr-361 passed, but default startup smoke fails and the generated API contract is stale for the new session-token flow.

Comment thread cmd/vpn-indexer/main.go Outdated
Comment thread internal/api/auth.go
@agaffney
agaffney force-pushed the feat/api-session-token branch 5 times, most recently from 86fefe4 to c7ea458 Compare June 30, 2026 19:44
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@agaffney

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown

@cubic-dev-ai review

@agaffney I have started the AI code review. It will take a few minutes to complete.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
docs/swagger.json (1)

742-748: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Document Bearer session authentication on protected operations.

These schemas no longer carry key/signature, but the Swagger spec does not add an Authorization: Bearer <token> security scheme/parameter for the client profile and WireGuard endpoints. Generated clients will have no documented way to authenticate.

Example Swagger 2.0 shape
 "basePath": "/",
+ "securityDefinitions": {
+     "BearerAuth": {
+         "type": "apiKey",
+         "name": "Authorization",
+         "in": "header",
+         "description": "Use: Bearer <session token>"
+     }
+ },
  "paths": {

Then add this to each bearer-protected operation:

 "post": {
+    "security": [
+        {
+            "BearerAuth": []
+        }
+    ],

Also applies to: 892-900, 928-934, 950-969

🤖 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 `@docs/swagger.json` around lines 742 - 748, The Swagger spec for the protected
client profile and WireGuard operations is missing Bearer session authentication
documentation, so generated clients won’t know how to authenticate. Update the
relevant operation definitions in swagger.json to include an Authorization
Bearer security scheme/parameter for each bearer-protected endpoint, and ensure
the protected operations reference that scheme consistently alongside the
existing api.ClientProfileRequest and WireGuard request schemas.
🤖 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 `@docs/swagger.json`:
- Around line 789-798: The api.SessionRequest schema currently leaves key and
signature optional, but handleAuthSession requires both fields, so update the
SessionRequest definition to mark key and signature as required. Make the change
in the swagger schema entry for api.SessionRequest so generated clients enforce
the same contract as the handler.

In `@docs/swagger.yaml`:
- Around line 52-58: The api.SessionRequest schema in the Swagger YAML currently
defines key and signature as optional, but the runtime requires both values.
Update the api.SessionRequest object definition to mark key and signature as
required so the schema matches the contract enforced by SessionRequest handling.

In `@internal/api/api.go`:
- Around line 63-74: Start should fail fast if jwtIssuer is nil instead of
letting Api register handlers that later dereference a.jwtIssuer and panic on
request handling. Add an explicit nil check in Start before constructing the Api
or calling registerAPI to return a startup error, using the jwtIssuer parameter
and the Api/registerAPI flow as the key places to update.

In `@internal/config/config.go`:
- Around line 233-237: The JWT key path is validated after trimming, but
vpn.JWTKeyFile still keeps the original whitespace-padded value, which can break
later initialization. In the config validation flow around the JWTKeyFile
handling, make sure the normalized value from strings.TrimSpace is written back
to vpn.JWTKeyFile before proceeding, so downstream code uses the same cleaned
path that passed validation.

---

Outside diff comments:
In `@docs/swagger.json`:
- Around line 742-748: The Swagger spec for the protected client profile and
WireGuard operations is missing Bearer session authentication documentation, so
generated clients won’t know how to authenticate. Update the relevant operation
definitions in swagger.json to include an Authorization Bearer security
scheme/parameter for each bearer-protected endpoint, and ensure the protected
operations reference that scheme consistently alongside the existing
api.ClientProfileRequest and WireGuard request schemas.
🪄 Autofix (Beta)

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: CHILL

Plan: Pro

Run ID: e57ccb65-45ea-4d3c-9641-14aebe000db8

📥 Commits

Reviewing files that changed from the base of the PR and between 155e7d0 and c7ea458.

📒 Files selected for processing (12)
  • cmd/vpn-indexer/main.go
  • docs/docs.go
  • docs/swagger.json
  • docs/swagger.yaml
  • internal/api/api.go
  • internal/api/auth.go
  • internal/api/client.go
  • internal/api/wireguard.go
  • internal/api/wireguard_test.go
  • internal/config/config.go
  • internal/jwt/issuer.go
  • internal/jwt/issuer_test.go
✅ Files skipped from review due to trivial changes (1)
  • docs/docs.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • cmd/vpn-indexer/main.go
  • internal/jwt/issuer_test.go
  • internal/jwt/issuer.go

Comment thread docs/swagger.json
Comment thread docs/swagger.yaml
Comment thread internal/api/api.go
Comment thread internal/config/config.go Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

7 issues found across 12 files

You’re at about 90% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/api/auth.go
Comment thread internal/api/client.go Outdated
Comment thread internal/config/config.go Outdated
Comment thread docs/docs.go
Comment thread internal/api/api.go
Comment thread internal/jwt/issuer.go
Comment thread docs/swagger.yaml
@agaffney
agaffney force-pushed the feat/api-session-token branch 5 times, most recently from e7e3079 to 580dc56 Compare June 30, 2026 20:27
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@agaffney

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown

@cubic-dev-ai review

@agaffney I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 12 files

You’re at about 91% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/swagger.yaml
Comment thread internal/jwt/issuer.go
@agaffney
agaffney force-pushed the feat/api-session-token branch from 580dc56 to 5364910 Compare June 30, 2026 20:42
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

4 issues found across 12 files

You’re at about 91% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="internal/api/client.go">

<violation number="1" location="internal/api/client.go:161">
P2: Database lookup failures from `authenticate` are now returned as 401 Unauthorized. Distinguish infrastructure/lookup errors from invalid session/ownership failures so profile requests don't hide server-side database outages as auth failures.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/api/client.go
Comment thread docs/docs.go
Comment thread docs/swagger.yaml
Comment thread internal/jwt/issuer.go Outdated
@agaffney
agaffney force-pushed the feat/api-session-token branch from 5364910 to 96a1d54 Compare June 30, 2026 21:46
@agaffney

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

3 issues found across 12 files

You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="internal/api/client.go">

<violation number="1" location="internal/api/client.go:161">
P2: Database lookup failures from `authenticate` are now returned as 401 Unauthorized. Distinguish infrastructure/lookup errors from invalid session/ownership failures so profile requests don't hide server-side database outages as auth failures.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/api/auth.go
Comment thread internal/api/auth.go
Comment thread internal/jwt/issuer.go
@agaffney
agaffney force-pushed the feat/api-session-token branch from 96a1d54 to 7ea1bff Compare June 30, 2026 21:57
@agaffney

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown

@cubic-dev-ai review

@agaffney I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 12 files

You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/jwt/issuer.go
Signed-off-by: Aurora Gaffney <aurora@blinklabs.io>
@agaffney
agaffney force-pushed the feat/api-session-token branch from 7ea1bff to 7ad6d1f Compare June 30, 2026 22:08
@agaffney
agaffney merged commit 85463d4 into main Jul 1, 2026
10 checks passed
@agaffney
agaffney deleted the feat/api-session-token branch July 1, 2026 16:22
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.

2 participants