feat(invites): 1 hour default TTL + optional per-mint ttl_secs#2072
Conversation
The 15 minute TTL killed invites before a human could hand the link and PIN to an agent operator: both of the maintainer's live-test invites expired unredeemed. Default is now 1 hour, and mint accepts an optional ttl_secs (60s to 24h) so a longer-lived invite is a deliberate choice at mint time rather than a code change. The PIN remains the security gate; expiry is hygiene. Tests: default lands at 1 hour, ttl_secs is honoured, over-cap is 422.
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughProject invite minting now supports optional TTL overrides bounded from 60 seconds to 24 hours. The default expiry increased from 15 minutes to one hour, and route tests cover default, custom, and rejected TTL values. ChangesProject invite TTL
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant mint_invite
participant ProjectInviteStore
Client->>mint_invite: Submit optional ttl_secs
mint_invite->>ProjectInviteStore: mint(ttl_secs)
ProjectInviteStore-->>mint_invite: Return invite with expires_ts
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
| expires_ts = now + _EXPIRY_SECS | ||
| if ttl_secs is not None and ttl_secs <= 0: | ||
| raise ValueError("ttl_secs must be positive") | ||
| expires_ts = now + (ttl_secs if ttl_secs is not None else _EXPIRY_SECS) |
There was a problem hiding this comment.
SUGGESTION: mint only enforces a lower bound on ttl_secs (> 0); the 24-hour hard cap lives solely in the route-layer Pydantic model (le=86400).
mint is a shared boundary called from multiple routes (project mint here, plus the OS-level mint call sites). If any current or future caller passes a ttl_secs that hasn't been route-validated, this line will silently mint an invite that lives far longer than the intended 24h cap — defeating the "no invite lives indefinitely" guarantee described in the PR. Consider clamping/validating the upper bound in the store itself so the invariant holds regardless of caller.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Optional - consider before merge Overview
Issue Details (click to expand)SUGGESTION
The change is small, focused, and well-tested. The default TTL bump (15m -> 1h), the optional Files Reviewed (3 files)
Fix these issues in Kilo Cloud Reviewed by hy3:free · Input: 70.6K · Output: 7.9K · Cached: 435.9K |
Follow-up to #2071, from the same live-test session: both invites expired before they could be redeemed because the TTL was 15 minutes.
Change
POST /api/projects/{id}/invitesaccepts optionalttl_secs(60s to 24h, validated); omitted uses the default.ProjectInviteStore.minttakesttl_secs=Noneand falls back to the default, so every other call site is unchanged.Rationale
Handing an invite URL + PIN to a human who then configures an agent is not a 15 minute flow. The PIN (plus the pending cap and single-use redeem) is the actual security control; expiry is hygiene, so an hour by default with an explicit opt-in up to a day is the right balance. 24h is a hard cap so no invite lives indefinitely.
Testing
ttl_secshonoured at the 24h bound, over-cap rejected 422.Follow-up
The mint dialog gets a TTL picker (15m / 1h / 24h) as part of the #2065 rework - the backend contract lands here first so the UI has something to call.
Summary by CodeRabbit