feat(cells): Add stub for synapse endpoint#105975
Conversation
| if not settings.SYNAPSE_AUTH_SECRET: | ||
| return False | ||
|
|
||
| return request.META.get("HTTP_X_SYNAPSE_AUTH") == settings.SYNAPSE_AUTH_SECRET |
There was a problem hiding this comment.
is this an acceptable way to lock down this endpoint? i saw similar approaches used elsewhere in this codebase
There was a problem hiding this comment.
Most of our other service-to-service requests are using payload/request hmac signatures. We should follow that pattern here so we can consolidate to a single implementation in the future.
|
🚨 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 |
| if not settings.SYNAPSE_AUTH_SECRET: | ||
| return False | ||
|
|
||
| return request.META.get("HTTP_X_SYNAPSE_AUTH") == settings.SYNAPSE_AUTH_SECRET |
There was a problem hiding this comment.
Most of our other service-to-service requests are using payload/request hmac signatures. We should follow that pattern here so we can consolidate to a single implementation in the future.
src/sentry/api/urls.py
Outdated
| ), | ||
| # Cell routing endpoints | ||
| re_path( | ||
| r"^org-cell-mappings/$", |
There was a problem hiding this comment.
Should this be under the /internal path like other internal API endpoints?
There was a problem hiding this comment.
Good idea, moved to the internal list
| class SynapseAuthPermission(BasePermission): | ||
| """ | ||
| Validates HMAC signature for Synapse requests. | ||
|
|
||
| Expects the X-Synapse-Signature header to contain the HMAC-SHA256 hex digest | ||
| of the request body, signed with SYNAPSE_AUTH_SECRET. | ||
| """ | ||
|
|
||
| def has_permission(self, request: Request, view: object) -> bool: | ||
| if settings.IS_DEV: | ||
| return True | ||
|
|
||
| if not settings.SYNAPSE_HMAC_SECRET: | ||
| return False | ||
|
|
||
| signature = request.META.get("HTTP_X_SYNAPSE_SIGNATURE") | ||
| if not signature: | ||
| return False | ||
|
|
||
| body_bytes = request.body if request.body not in (None, b"") else b"" | ||
|
|
||
| computed_hmac = hmac.new( | ||
| settings.SYNAPSE_HMAC_SECRET.encode("utf-8"), | ||
| body_bytes, | ||
| hashlib.sha256, | ||
| ).hexdigest() | ||
|
|
||
| return hmac.compare_digest(signature, computed_hmac) |
There was a problem hiding this comment.
Typically we implement this logic in an authentication adapter. We should be able to use the existing generic signature adapter:
sentry/src/sentry/api/authentication.py
Lines 707 to 743 in 203f0a1
| class OrgCellMappingsEndpoint(Endpoint): | ||
| """ | ||
| Returns the organization-to-cell mappings for all orgs in pages. | ||
| Only accessible by the Synapse internal service via X-Synapse-Auth header. | ||
| """ | ||
|
|
||
| owner = ApiOwner.INFRA_ENG | ||
| publish_status = { | ||
| "GET": ApiPublishStatus.PRIVATE, | ||
| } | ||
| permission_classes = (SynapseAuthPermission,) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
src/sentry/conf/server.py
Outdated
| CONDUIT_PUBLISH_JWT_ISSUER: str = os.getenv("CONDUIT_PUBLISH_JWT_ISSUER", "sentry.io") | ||
| CONDUIT_PUBLISH_JWT_AUDIENCE: str = os.getenv("CONDUIT_PUBLISH_JWT_AUDIENCE", "conduit") | ||
|
|
||
| SYNAPSE_HMAC_SECRET: str | None = os.getenv("SYNAPSE_HMAC_SECRET") |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
I added a linear task so we don't forget to add this secret in.
to match hmac auth added in getsentry/sentry#105975
to match hmac auth added in getsentry/sentry#105975
to be based on #106231