Skip to content

feat(secret-sharing): cleaned up API and exposed publicly #5427

Merged
varonix0 merged 11 commits intomainfrom
daniel/secret-sharing-api
Feb 13, 2026
Merged

feat(secret-sharing): cleaned up API and exposed publicly #5427
varonix0 merged 11 commits intomainfrom
daniel/secret-sharing-api

Conversation

@varonix0
Copy link
Member

@varonix0 varonix0 commented Feb 10, 2026

Context

I've cleaned up the secret sharing API and added identity support. I haven't done much work on the requests side of things. If we expose the secret requests router, we can clean that one up more as well. The requests router is in much better shape than the secret sharing router was prior to this PR though.

Secret Sharing API - Before & After

Route Changes

Before After Notes
GET /api/v1/secret-sharing/shared/ GET /api/v1/secret-sharing/ Removed redundant /shared prefix
POST /api/v1/secret-sharing/shared/public/:id POST /api/v1/secret-sharing/:id/access Changed from POST for read to action-based endpoint. Removed /public segment.
(none) GET /api/v1/secret-sharing/:id New endpoint - Fetches secret metadata without revealing the value. Enables two-step access flow. Before you would hit the (now) /access endpoint, which would give you an error and an isPasswordProtected field. Then you knew you need to re-hit the same API endpoint with a password. Not restful.
POST /api/v1/secret-sharing/shared/ POST /api/v1/secret-sharing/ Removed /shared prefix
DELETE /api/v1/secret-sharing/shared/:id DELETE /api/v1/secret-sharing/:id Removed /shared prefix

Behavioral Changes

GET /api/v1/secret-sharing/:id (New)

  • Returns full secret metadata (without secret value)
  • Auth logic: No auth for accessType: "anyone", requires auth + org check for accessType: "organization"
  • Enables frontend to determine if password prompt is needed before attempting access

POST /:id/access

  • Renamed from POST /public/:id for clarity (it's an action, not a resource read)
  • Removed brandingConfig from response (now fetched separately via GET /branding?sharedSecretId=...)
  • Removed error field from response (errors now use proper HTTP status codes)

Response Schema Changes

Before (POST /public/:id):

{
  isPasswordProtected: boolean;
  secret?: {
    secretValue?: string;
    // other fields
  };
  brandingConfig?: {}; // now removed
  error?: string;           // now removed
}

After (GET /:id):

{
  id: string;
  name: string | null;
  accessType: "organization" | "anyone";
  expiresAt: string;
  expiresAfterViews: number | null;
  isPasswordProtected: boolean;
  // ... full sanitized secret (no secret value)
}

After (POST /:id/access) - new endpoint:

{
  id: string;
  name: string | null;
  accessType: "organization" | "anyone";
  expiresAt: string;
  secretValue?: string;      // The actual secret
  orgName?: string;
  // ... full sanitized secret
}

Frontend Flow Change

Before:

  1. POST /public/:id: Returns everything in one call (metadata + secret value + branding). Would be called multiple times in the frontend for password protected secrets.
    After:
  2. GET /:id: Get metadata (is it password protected? what access type?)
  3. If not password protected: automatically call POST /:id/access
  4. If password protected: show password prompt, then call POST /:id/access with password
  5. GET /branding?sharedSecretId=..., fetch branding separately

Breaking changes

In the past, secret sharing was end-to-end encrypted. We used to look up secrets using a combination of the secret's UUIDv4 ID and a hashed hex. This is over 14 months old, and I've now removed this logic from the API. This means that shared secrets that are over 14 months old will no longer work. This is not a problem, as secrets are set to expire at the latest after 30 days.

Steps to verify the change

Type

  • Fix
  • Feature
  • Improvement
  • Breaking
  • Docs
  • Chore

Checklist

  • Title follows the conventional commit format: type(scope): short description (scope is optional, e.g., fix: prevent crash on sync or fix(api): handle null response).
  • Tested locally
  • Updated docs (if needed)
  • Read the contributing guide

@varonix0 varonix0 self-assigned this Feb 10, 2026
@maidul98
Copy link
Collaborator

maidul98 commented Feb 10, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@varonix0
Copy link
Member Author

@greptile why did you stop reviewing the PR? review my PR!

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 10, 2026

Greptile Overview

Greptile Summary

This PR refactors/exposes the v1 secret-sharing API, adds identity support for shared secrets, and updates docs/frontend accordingly. It introduces a DB migration adding identityId to secret-sharing records, updates Zod schemas/sanitized response shapes, and refreshes public/organization UIs and API hooks to match the new endpoints and request/response fields.

Confidence Score: 2/5

  • This PR should not be merged until a couple of correctness/security issues in the new public secret-sharing surface are addressed.
  • Score reflects newly-exposed public routes and input validation changes; review indicates at least one definite runtime/validation bug plus additional security-sensitive behavior changes that require fixes before merge.
  • backend/src/server/routes/v1/secret-requests-router.ts, backend/src/server/routes/v1/secret-sharing-router.ts, backend/src/services/secret-sharing/secret-sharing-dal.ts, backend/src/db/migrations/20260210210927_secret-sharing-identity-support.ts

Important Files Changed

Filename Overview
backend/src/db/migrations/20260210210927_secret-sharing-identity-support.ts Adds migration to support identity-based secret sharing; main risk is non-idempotent operations or missing down/guards.
backend/src/server/routes/v1/secret-requests-router.ts Refactors/exports secret requests router; check authorization for request creation/read and public exposure implications.
backend/src/server/routes/v1/secret-sharing-router.ts Cleans up secret sharing API routes and adds identity support; review for breaking API changes and unauthenticated info leaks.
backend/src/services/secret-sharing/secret-sharing-dal.ts Updates DAL queries to support identity actors and new filters; watch for unsafe OR/grouping and tenant/creator scoping.
backend/src/services/secret-sharing/secret-sharing-service.ts Service logic updated for identity support and API cleanup; review authorization branches and audit log/metadata correctness.
docs/api-reference/endpoints/secret-sharing/shared-secrets/create.mdx Docs updated for create shared secret; aligns with authorizedEmails and identity support.
frontend/src/hooks/api/secretSharing/mutations.ts Updates secret sharing mutations to match cleaned API; verify request payload keys and routes match backend.
frontend/src/pages/public/ViewSharedSecretByIDPage/ViewSharedSecretByIDPage.tsx Adjusts public view shared secret page for new API responses; ensure no runtime crash on missing fields.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

27 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@varonix0
Copy link
Member Author

@greptile re-review PR with my comments to your comments in mind and update your summary

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

27 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@varonix0 varonix0 requested a review from maidul98 February 11, 2026 00:43
Copy link
Collaborator

@maidul98 maidul98 left a comment

Choose a reason for hiding this comment

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

secret-sharing sounds odd as an API. i think it would make more sense for it to be:

  • /api/v1/shared-secrets/
  • GET /api/v1/shared-secrets/:id
  • POST /api/v1/shared-secrets/:id/access
  • DELETE /api/v1/shared-secrets/:id

also what happens to all of the old share links right before this change? wil we handle redirects?

Copy link
Collaborator

@maidul98 maidul98 left a comment

Choose a reason for hiding this comment

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

some nits

@varonix0 varonix0 merged commit aff7306 into main Feb 13, 2026
12 of 14 checks passed
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