feat(hub): secret intake links — secure secret submission from chat - #318
feat(hub): secret intake links — secure secret submission from chat#318zeroasterisk wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements Secret Intake Links, enabling secure secret submission from chat channels via short-lived, one-time-use URLs. It adds a CLI command, backend handlers, an in-memory SecretIntakeService, and a standalone frontend page for anonymous submission. The review feedback identifies several critical issues: a concurrency data race on SecretIntake fields between handlers and the background cleanup loop; a client-side JWT decoding bug due to missing base64 padding and lack of UTF-8 support; a potential memory-exhaustion DoS vulnerability from a missing size limit on submitted values; a validation gap where scope_id is not verified for project-scoped secrets; loose path matching in the unauthenticated endpoint check; and a bug where trimming whitespace from submitted secrets can corrupt keys with significant whitespace.
|
could said link basically just bring you to the new secret dialog in the linked project the secret intake with no login, then confirmation in chat seems like a mild security risk surface |
|
Thanks for the feedback! We were going for a more versatile and zero-friction approach (works even if the user isn't near a browser session), but you're right that the no-login surface is unnecessary risk. Switching to a deep-link into the Hub UI with a simplified, focused secret-entry screen. The user must be logged in, the link pre-fills the key/scope/project/type from a JWT, and we'll send a notification to chat when the secret is stored. Dropping the anonymous intake page and the confirmation step. |
3e3da3f to
9cbfdc9
Compare
|
Round 3 review complete — 3 clean cycles, no new findings. Rebased on upstream/main (resolved 4 merge conflicts in server.go from upstream Discord link service additions). All tests pass. Design simplified per maintainer feedback: authenticated deep-link, no anonymous endpoints, no OTP/confirmation flow. 12 tests. |
8d1bf6c to
495021e
Compare
This is what we did |
495021e to
c84a492
Compare
c84a492 to
03fb52c
Compare
|
I think I might have come up with a much more elegant approach to this, which would use native bot commands in the chat system. I would allow a user to send secrets directly to the control plane, not via an agent, and it would not be visible to other users in the chat. There then has to be a companion issue about how agents actually receive or retrieve secrets that were created after they were provisioned, but that's at least a separate issue. |
Problem
When users interact with Scion agents via chat (Telegram, Discord), agents sometimes need secrets. Today users must leave the chat to use the CLI/web UI, or paste secrets in plaintext — a security anti-pattern that has already happened in practice (a raw GitHub PAT was pasted into Telegram in this project's own history).
Solution
Secret intake links: a short-lived, JWT-secured URL that lets users paste a secret directly into the Hub, with a two-step confirmation flow to prevent injection attacks.
User flow
Security model
Alternatives considered
We chose intake links as the best tradeoff between security and UX for the chat context.
Reviewability roadmap
This is ~1,865 lines but the core logic is in one file:
pkg/hub/secret_intake.go— theSecretIntakeService: JWT generation, rate limiting, full lifecycle (create → submit → confirm/reject). Follows the existingTelegramLinkServicepattern.pkg/hub/secret_intake_test.go— 12 tests covering the full lifecycle + security edge casespkg/hubclient/secret_intake.go— SDK client (thin wrapper)cmd/hub_secret_intake.go— CLI commandscion hub secret intake KEYweb/src/components/pages/secret-intake.ts— Lit component for the intake pageserver.go(routes),auth.go(exempt submit endpoint — JWT is the auth)This PR could be split if you'd prefer to review the backend (Go) and frontend (Lit) separately — happy to do that on request.
Risk