Skip to content

feat(cmd-k): Add DSN lookup API endpoint#108400

Open
sergical wants to merge 9 commits intomasterfrom
sergical/cmd-k-dsn-lookup-backend
Open

feat(cmd-k): Add DSN lookup API endpoint#108400
sergical wants to merge 9 commits intomasterfrom
sergical/cmd-k-dsn-lookup-backend

Conversation

@sergical
Copy link
Member

@sergical sergical commented Feb 17, 2026

Summary

Adds a private API endpoint that resolves a Sentry DSN to its associated project and key metadata. This powers the command palette (Cmd+K) — users can paste a DSN and quickly navigate to the corresponding project.

Endpoint: GET /api/0/organizations/{org}/dsn-lookup/?dsn=<dsn>

Behavior:

  • Parses the DSN to extract the public key, then looks up the matching ProjectKey scoped to the requesting organization
  • Returns project slug, ID, name, platform, and key label/ID
  • Returns 404 for invalid DSNs, unknown keys, or keys belonging to projects outside the org

Access control:

  • OrganizationEndpoint base class enforces org membership
  • ProjectKey query is scoped by project__organization_id to prevent IDOR
  • Gated behind the organizations:cmd-k-dsn-lookup feature flag
  • Rate limited to 5 req/s per user

Context

Split from #108396 — this is the backend half. The frontend PR (command palette integration) will follow and reference this PR as a dependency.

Test plan

  • Backend tests pass (pytest tests/sentry/api/endpoints/test_dsn_lookup.py)
  • CI passes

Add a new API endpoint that allows looking up project DSNs by their
public key portion. This powers the command palette DSN lookup feature
behind the organizations:cmd-k-dsn-lookup feature flag.
@sergical sergical requested review from a team as code owners February 17, 2026 22:30
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 17, 2026
sergical added a commit that referenced this pull request Feb 17, 2026
Add DSN lookup functionality to both the new supercharged command
palette and the legacy search modal. Users can paste a DSN and get
quick navigation to the corresponding project.

Depends on backend PR #108400.
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Feb 17, 2026
@github-actions
Copy link
Contributor

🚨 Warning: This pull request contains Frontend and Backend changes!

It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently.

Have questions? Please ask in the #discuss-dev-infra channel.

The endpoint was missing the organizations:cmd-k-dsn-lookup feature flag
check, making it accessible to any authenticated user regardless of
whether the feature was enabled for their org.

Also removes a broken unauthenticated test (silo mode issue with
client.logout in region silo) and adds a test for the flag-disabled case.
Fixes mypy union-attr errors where ProjectKey | None was accessed
without narrowing.
Copy link
Member

@JoshFerge JoshFerge left a comment

Choose a reason for hiding this comment

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

I believe this introduces a security vulnerability as is as we're not checking that the user has access to the project key. can we:

  • use ProjectEndpoint or OrganizationEndpoint, which makes sure the user making request has access to the org/project?

  • in the ProjectKey lookup, make sure we're adding project to the ORM query so we prevent IDOR attacks?

mind adding a bit of description to the PR / endpoint docstring? from reading this i'm not quite sure what the intended use of the endpoint is (a user gives a dsn and it gets back info about it?)


try:
parsed = urlparse(dsn)
except Exception:
Copy link
Member

Choose a reason for hiding this comment

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

blanket exception handling is not ideal. how exactly can urlparse error? I assume it returns an error more specific than Exception.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call — removed the try/except entirely. urlparse is extremely permissive and basically never raises; request.GET.get() always returns str | None and we already guard None/empty above. Invalid DSNs (like "not-a-dsn") just produce a parsed result with no username, which the if not public_key check handles.

Copy link
Member

@JoshFerge JoshFerge left a comment

Choose a reason for hiding this comment

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

and if this is intended to be a user scoped endpoint, can we use UserEndpoint?

class UserEndpoint(Endpoint):

sergical and others added 2 commits February 17, 2026 17:44
Address security review feedback:
- Switch from bare Endpoint to OrganizationEndpoint so auth and org
  access are handled by the base class
- Scope ProjectKey query with project__organization_id to prevent IDOR
- Move URL from /api/0/dsn-lookup/ to
  /api/0/organizations/{org}/dsn-lookup/
- Add endpoint docstring explaining the use case
- Remove manual OrganizationMember check (now handled by base class)
urlparse only raises for non-string input, but request.GET.get()
always returns str | None and we already guard against None/empty.
Invalid DSNs are handled by the subsequent `if not public_key` check.
@sergical
Copy link
Member Author

Re: UserEndpoint suggestion — this endpoint is org-scoped: the feature flag is per-org, and the DSN belongs to a project within that org. We switched to OrganizationEndpoint (which enforces org membership) and scope the ProjectKey query by project__organization_id. So OrganizationEndpoint is the right fit here.

Latest push removes the blanket except Exception around urlparse as well.

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Only resolve DSNs for active projects, active keys, and user-facing
keys. Prevents returning metadata for deleted projects, inactive keys,
or internal keys (e.g. profiling, escalating_issues).
Copy link
Member

@JoshFerge JoshFerge left a comment

Choose a reason for hiding this comment

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

looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants