Skip to content

feat: relayauth integration — JWT verification + scope enforcement#102

Open
khaliqgant wants to merge 1 commit intomainfrom
feat/relayauth-integration
Open

feat: relayauth integration — JWT verification + scope enforcement#102
khaliqgant wants to merge 1 commit intomainfrom
feat/relayauth-integration

Conversation

@khaliqgant
Copy link
Member

@khaliqgant khaliqgant commented Mar 24, 2026

Summary

Adds workflow (workflows/integrate-relayauth.ts) to integrate relayauth into relaycast:

  • Replace opaque rk_live_ token auth with relayauth JWT verification via JWKS
  • Scope enforcement: relaycast:channel:read, relaycast:dm:send, etc.
  • Backwards compatible — existing tokens still work as fallback
  • SponsorChain propagated to request context

Depends on

  • @relayauth/sdk (TokenVerifier, ScopeChecker) — not yet published

Run

agent-relay run workflows/integrate-relayauth.ts

🤖 Generated with Claude Code


Open with Devin

Workflow to replace relaycast's opaque token auth with relayauth JWT
verification. Adds scope enforcement (relaycast:channel:read, etc.),
backwards compat with existing rk_live_ tokens, and sponsorChain
propagation.

Depends on: @relayauth/sdk

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 3 potential issues.

View 4 additional findings in Devin Review.

Open in Devin Review

.step('run-tests', {
type: 'deterministic',
dependsOn: ['verify-files'],
command: `cd ${RELAYCAST} && npx turbo typecheck 2>&1 | tail -15; echo "EXIT: $?"`,

Choose a reason for hiding this comment

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

🔴 $? captures tail's exit code instead of turbo typecheck's, always showing EXIT: 0

On line 223, the command npx turbo typecheck 2>&1 | tail -15; echo "EXIT: $?" captures the exit code of tail (the last command in the pipeline), not npx turbo typecheck. Since tail virtually always succeeds, $? will always be 0, meaning the downstream review and fix steps (which consume {{steps.run-tests.output}}) will always see "EXIT: 0" even when the typecheck fails. This gives the reviewer and architect agents misleading information about whether the typecheck passed. The fix is to use ${PIPESTATUS[0]} instead of $?.

Suggested change
command: `cd ${RELAYCAST} && npx turbo typecheck 2>&1 | tail -15; echo "EXIT: $?"`,
command: `cd ${RELAYCAST} && npx turbo typecheck 2>&1 | tail -15; echo "EXIT: \${PIPESTATUS[0]}"`,
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +71 to +75
.step('read-worker', {
type: 'deterministic',
command: `cat ${RELAYCAST}/packages/server/src/worker.ts`,
captureOutput: true,
})

Choose a reason for hiding this comment

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

🟡 read-worker and read-relayauth-errors steps are orphaned — outputs never consumed

The read-worker step (line 71) and read-relayauth-errors step (line 89) capture file output but are never referenced in any dependsOn array or {{steps.*.output}} template. This means their output is wasted. Notably, read-relayauth-errors reads errors.ts which contains InsufficientScopeError — the exact type the implement-scopes step (line 175) instructs the agent to use for 403 responses. Without this context, the scope-dev agent won't know the error type's API. Similarly, read-worker reads how middleware is wired, which would be useful for the implement-auth step.

Prompt for agents
In workflows/integrate-relayauth.ts, two steps are defined but never consumed:

1. read-worker (line 71-75): Add 'read-worker' to the dependsOn array of the implement-auth step (line 139) and reference its output via {{steps.read-worker.output}} in the implement-auth task template (around line 140-172).

2. read-relayauth-errors (line 89-93): Add 'read-relayauth-errors' to the dependsOn array of the implement-scopes step (line 177) and reference its output via {{steps.read-relayauth-errors.output}} in the implement-scopes task template (around line 178-207), so the scope-dev agent knows about InsufficientScopeError.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +251 to +261
.step('fix', {
agent: 'architect',
dependsOn: ['review'],
task: `Fix any issues from the review and typecheck.

Typecheck: {{steps.run-tests.output}}
Review: {{steps.review.output}}

Fix all issues. Run typecheck again to verify.`,
verification: { type: 'exit_code' },
})

Choose a reason for hiding this comment

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

🔴 AGENTS.md violation: no steps to update README.md and openapi.yaml for API behavior changes

AGENTS.md requires: "Update README.md and openapi.yaml together when API behavior changes." This workflow introduces JWT authentication and scope-based authorization (new 403 responses on scope failures), which are significant API behavior changes. However, the workflow contains no steps to update README.md or openapi.yaml. The current openapi.yaml (line 7) only documents rk_live_* and at_live_* auth, and README.md has no mention of JWT auth. After this workflow runs, the docs will be stale and out of sync with the new auth behavior.

Prompt for agents
In workflows/integrate-relayauth.ts, add a new step (e.g., 'update-docs') after the 'fix' step that instructs an agent to update README.md and openapi.yaml to document the new JWT authentication method and scope-based authorization. Specifically:

1. Update openapi.yaml to add a new securityScheme for relayauth JWT tokens alongside the existing workspaceKey and agentToken schemes (around openapi.yaml line 27-35), and document the new 403 scope error responses.
2. Update README.md to mention JWT authentication via relayauth as an alternative auth method.

This is required by the AGENTS.md docs hygiene rule: 'Update README.md and openapi.yaml together when API behavior changes.'
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@github-actions
Copy link

Preview deployed!

Environment URL
API https://pr102-api.relaycast.dev
Health https://pr102-api.relaycast.dev/health
Observer https://pr102-observer.relaycast.dev/observer

This preview shares the staging database and will be cleaned up when the PR is merged or closed.

Run E2E tests

npm run e2e -- https://pr102-api.relaycast.dev --ci

Open observer dashboard

https://pr102-observer.relaycast.dev/observer

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