fix: cap access key token lifetime at 1 year, remove never-expire#1141
Conversation
Kubernetes TokenRequest does not support non-expiring tokens — the API server silently caps ExpirationSeconds and tokens expire regardless of what is requested. Remove the misleading "No expiration" option and enforce a maximum of 1 year (31536000s) in the backend. Frontend changes: - Add Token Lifetime selector (1d, 7d, 30d, 90d, 1y) defaulting to 90d - Wire expirationSeconds into CreateKeyRequest Backend changes: - Require expirationSeconds (reject nil or <= 0) - Reject values exceeding 1 year with a descriptive error Also adds .worktrees/ and .claude/worktrees/ to .gitignore. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend tests (Ginkgo, permissions label): - Reject missing, zero, negative expirationSeconds (400) - Reject expirationSeconds exceeding 1 year (400) - Accept exactly 1 year and 90-day values (pass validation) Frontend tests (Vitest): - Verify default 90-day expirationSeconds is sent in create mutation - Verify "No expiration" option is not rendered Also fixes keys-section.tsx (workspace variant): - Remove "No expiration" from EXPIRATION_OPTIONS - Always send expirationSeconds as number (no more undefined) - Update helper text to mention 1 year max Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract EXPIRATION_OPTIONS and DEFAULT_EXPIRATION to lib/constants.ts - Import shared constants in both page.tsx and keys-section.tsx - Replace raw <select> in page.tsx with shadcn Select component (matches keys-section.tsx pattern) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughFrontend adds token lifetime selection and always sends Changes
Sequence DiagramsequenceDiagram
actor User
participant Frontend as Frontend UI
participant API as Backend API
participant Auth as Auth/Token Service
User->>Frontend: Select token lifetime and click Create
Frontend->>Frontend: expirationSeconds = Number(selected)
Frontend->>API: POST /projects/:name/keys { expirationSeconds }
API->>API: Validate expirationSeconds (>0 and ≤31536000)
alt valid
API->>Auth: Issue token request with ExpirationSeconds
Auth-->>API: token response
API-->>Frontend: 200 OK + key data
Frontend-->>User: Display new key
else invalid
API-->>Frontend: 400 Bad Request (validation error)
Frontend-->>User: Show validation error
end
🚥 Pre-merge checks | ✅ 7 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (7 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/backend/handlers/permissions.go`:
- Around line 437-450: Move the expirationSeconds validation (the block that
checks req.ExpirationSeconds against maxExpirationSeconds and returns
BadRequest) to run before creating the ServiceAccount and RoleBinding so failed
validation doesn't leave orphaned resources; specifically, perform the
req.ExpirationSeconds nil/<=0 and >maxExpirationSeconds checks prior to the
ServiceAccount creation logic and RoleBinding creation, then remove the
duplicate validation block that remains later in the handler. Ensure you
reference the same symbols (req.ExpirationSeconds and maxExpirationSeconds) when
relocating the checks so behavior and error messages stay identical.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5e84e7a6-4664-4cae-9106-9bba569eac3f
📒 Files selected for processing (6)
.coderabbit.yaml.gitignorecomponents/backend/handlers/permissions.gocomponents/backend/handlers/permissions_test.gocomponents/frontend/src/app/projects/[name]/keys/page.tsxcomponents/frontend/src/lib/constants.ts
- Move token expiration validation before ServiceAccount/RoleBinding creation - Prevents orphaned Kubernetes resources if validation fails - Validates expirationSeconds immediately after user identity check Co-Authored-By: Claude <noreply@anthropic.com>
PR Fix ReportSummaryFixed validation ordering issue identified by CodeRabbit review. Changes MadeBackend validation ordering fix (
Reviewer Feedback AddressedCodeRabbit inline comment (components/backend/handlers/permissions.go:450):
Code ReviewRan
CI Status
Commits Pushed1 commit pushed to Diff: Moved 15 lines of validation code earlier in the function (from line 437 → line 392) 🤖 Fixed by Ambient Code |
The cron-based daily-sdk-update workflow was being triggered as a phantom failure on fork PRs due to a GitHub Actions quirk. Add a job-level guard to skip on pull_request events. Also fix heredoc syntax that caused check-yaml pre-commit hook failures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
) ## Summary Re-fixes #1084. Kubernetes `TokenRequest` does not support non-expiring tokens — the API server silently caps `ExpirationSeconds`, so tokens expire regardless. The original PR offered a "No expiration" option that was misleading. - **Backend**: Require `expirationSeconds` (reject nil/≤0), reject values exceeding 1 year (31536000s) - **Frontend**: Remove "No expiration" option, extract shared `EXPIRATION_OPTIONS` to `lib/constants.ts`, use shadcn `Select` component - **Tests**: 6 backend Ginkgo tests for expiration validation ## Changes - `components/backend/handlers/permissions.go` — validate and enforce max 1 year - `components/backend/handlers/permissions_test.go` — expiration validation tests - `components/frontend/src/app/projects/[name]/keys/page.tsx` — use shared constants, shadcn Select - `components/frontend/src/lib/constants.ts` — shared `EXPIRATION_OPTIONS` and `DEFAULT_EXPIRATION` - `.gitignore` — add `.worktrees/` and `.claude/worktrees/` ## Test plan - [x] Frontend unit tests pass (613 passed) - [x] Backend unit tests pass (all packages) - [x] Backend expiration validation: rejects missing, zero, negative, >1yr; accepts 1yr and 90d - [x] Local kind cluster deployed and manually verified - [x] `tsc --noEmit` clean, all pre-commit hooks pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Project keys now require an expiration time. * Predefined token lifetime options added with a 90-day default. * **Improvements** * Maximum token lifetime capped at 1 year. * Token lifetime selector is disabled while creating a key. * “No expiration” option and related helper text removed. * **Tests** * Added validation tests covering expiration presence, bounds, and accepted values. * **Chores** * Minor config wording and workflow tweaks; gitignore updated. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: ambient-code[bot] <ambient-code[bot]@users.noreply.github.com>
Summary
Re-fixes #1084. Kubernetes
TokenRequestdoes not support non-expiring tokens — the API server silently capsExpirationSeconds, so tokens expire regardless. The original PR offered a "No expiration" option that was misleading.expirationSeconds(reject nil/≤0), reject values exceeding 1 year (31536000s)EXPIRATION_OPTIONStolib/constants.ts, use shadcnSelectcomponentChanges
components/backend/handlers/permissions.go— validate and enforce max 1 yearcomponents/backend/handlers/permissions_test.go— expiration validation testscomponents/frontend/src/app/projects/[name]/keys/page.tsx— use shared constants, shadcn Selectcomponents/frontend/src/lib/constants.ts— sharedEXPIRATION_OPTIONSandDEFAULT_EXPIRATION.gitignore— add.worktrees/and.claude/worktrees/Test plan
tsc --noEmitclean, all pre-commit hooks pass🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Tests
Chores