From 49979b770a6d1b5d0197b85be17ffc1871116878 Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Thu, 18 Dec 2025 10:10:23 -0500 Subject: [PATCH 01/11] Add constants and default options --- src/sentry/constants.py | 4 +++ .../core/endpoints/organization_details.py | 19 +++++++++++++ src/sentry/options/defaults.py | 27 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/sentry/constants.py b/src/sentry/constants.py index bc589e77378b..1eb43c02eddf 100644 --- a/src/sentry/constants.py +++ b/src/sentry/constants.py @@ -732,9 +732,13 @@ class InsightModules(Enum): # Org level setting to allow/disallow Projects to delegate Seer scanner automation to other LLMS ALLOW_BACKGROUND_AGENT_DELEGATION = True ENABLED_CONSOLE_PLATFORMS_DEFAULT: list[str] = [] +CONSOLE_SDK_INVITE_QUOTA_DEFAULT = 0 ENABLE_PR_REVIEW_TEST_GENERATION_DEFAULT = False INGEST_THROUGH_TRUSTED_RELAYS_ONLY_DEFAULT = "disabled" +# Repository owner for console SDK repositories +CONSOLE_SDK_REPO_OWNER = "alexsohn1126" + # `sentry:events_member_admin` - controls whether the 'member' role gets the event:admin scope EVENTS_MEMBER_ADMIN_DEFAULT = True ALERTS_MEMBER_WRITE_DEFAULT = True diff --git a/src/sentry/core/endpoints/organization_details.py b/src/sentry/core/endpoints/organization_details.py index a14188f27ba1..c0e31d74c65b 100644 --- a/src/sentry/core/endpoints/organization_details.py +++ b/src/sentry/core/endpoints/organization_details.py @@ -46,6 +46,7 @@ ATTACHMENTS_ROLE_DEFAULT, AUTO_ENABLE_CODE_REVIEW, AUTO_OPEN_PRS_DEFAULT, + CONSOLE_SDK_INVITE_QUOTA_DEFAULT, DEBUG_FILES_ROLE_DEFAULT, DEFAULT_AUTOFIX_AUTOMATION_TUNING_DEFAULT, DEFAULT_CODE_REVIEW_TRIGGERS, @@ -284,6 +285,12 @@ list, ENABLED_CONSOLE_PLATFORMS_DEFAULT, ), + ( + "consoleSdkInviteQuota", + "sentry:console_sdk_invite_quota_limit", + int, + CONSOLE_SDK_INVITE_QUOTA_DEFAULT, + ), ) DELETION_STATUSES = frozenset( @@ -355,6 +362,7 @@ class OrganizationSerializer(BaseOrganizationSerializer): required=False, allow_empty=True, ) + consoleSdkInviteQuota = serializers.IntegerField(required=False, min_value=0) enablePrReviewTestGeneration = serializers.BooleanField(required=False) enableSeerEnhancedAlerts = serializers.BooleanField(required=False) enableSeerCoding = serializers.BooleanField(required=False) @@ -461,6 +469,16 @@ def validate_enabledConsolePlatforms(self, value): return value + def validate_consoleSdkInviteQuota(self, value): + request = self.context["request"] + + if not is_active_staff(request): + raise serializers.ValidationError( + "Only staff members can change console SDK invite quota limit." + ) + + return value + def validate_targetSampleRate(self, value): organization = self.context["organization"] request = self.context["request"] @@ -854,6 +872,7 @@ def create_console_platform_audit_log( "allowBackgroundAgentDelegation", "ingestThroughTrustedRelaysOnly", "enabledConsolePlatforms", + "consoleSdkInviteQuota", ] ) class OrganizationDetailsPutSerializer(serializers.Serializer): diff --git a/src/sentry/options/defaults.py b/src/sentry/options/defaults.py index e9efe8d2e33e..035947d56e95 100644 --- a/src/sentry/options/defaults.py +++ b/src/sentry/options/defaults.py @@ -698,6 +698,33 @@ register("github-app.client-id", flags=FLAG_PRIORITIZE_DISK | FLAG_AUTOMATOR_MODIFIABLE) register("github-app.client-secret", flags=FLAG_CREDENTIAL | FLAG_PRIORITIZE_DISK) +# GitHub Console SDK App (separate app for repository invitations) +register( + "github-console-sdk-app.id", + default=0, + flags=FLAG_AUTOMATOR_MODIFIABLE | FLAG_ALLOW_EMPTY, +) +register( + "github-console-sdk-app.client-id", + default="", + flags=FLAG_AUTOMATOR_MODIFIABLE | FLAG_ALLOW_EMPTY, +) +register( + "github-console-sdk-app.installation-id", + default="", + flags=FLAG_CREDENTIAL | FLAG_ALLOW_EMPTY, +) +register( + "github-console-sdk-app.client-secret", + default="", + flags=FLAG_CREDENTIAL | FLAG_ALLOW_EMPTY, +) +register( + "github-console-sdk-app.private-key", + default="", + flags=FLAG_CREDENTIAL | FLAG_ALLOW_EMPTY, +) + # Github Enterprise Integration register( "github-enterprise-app.allowed-hosts-legacy-webhooks", From a1f26a69b4278cb45cd9f33803a8403903d5e2b2 Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Fri, 19 Dec 2025 13:56:39 -0500 Subject: [PATCH 02/11] add initial files --- src/sentry/hybridcloud/outbox/category.py | 2 ++ src/sentry/receivers/outbox/control.py | 10 ++++++++++ src/sentry/users/models/identity.py | 18 +++++++++++++++++- tests/sentry/receivers/outbox/test_control.py | 9 +++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/sentry/hybridcloud/outbox/category.py b/src/sentry/hybridcloud/outbox/category.py index 469caf0832f7..b440ff516965 100644 --- a/src/sentry/hybridcloud/outbox/category.py +++ b/src/sentry/hybridcloud/outbox/category.py @@ -63,6 +63,7 @@ class OutboxCategory(IntEnum): SERVICE_HOOK_UPDATE = 40 SENTRY_APP_DELETE = 41 SENTRY_APP_INSTALLATION_DELETE = 42 + IDENTITY_UPDATE = 43 @classmethod def as_choices(cls) -> Sequence[tuple[int, int]]: @@ -282,6 +283,7 @@ class OutboxScope(IntEnum): OutboxCategory.UNUSED_TWO, OutboxCategory.UNUSUED_THREE, OutboxCategory.AUTH_IDENTITY_UPDATE, + OutboxCategory.IDENTITY_UPDATE, }, ) # Webhook scope is no longer in use diff --git a/src/sentry/receivers/outbox/control.py b/src/sentry/receivers/outbox/control.py index 3f90cb1d7151..46d12b26583f 100644 --- a/src/sentry/receivers/outbox/control.py +++ b/src/sentry/receivers/outbox/control.py @@ -26,6 +26,7 @@ from sentry.sentry_apps.models.sentry_app_installation import SentryAppInstallation from sentry.sentry_apps.services.hook.service import hook_service from sentry.sentry_apps.tasks.sentry_apps import clear_region_cache +from sentry.users.models.identity import Identity from sentry.workflow_engine.service.action.service import action_service logger = logging.getLogger(__name__) @@ -42,6 +43,15 @@ def process_integration_updates(object_identifier: int, region_name: str, **kwds integration # Currently we do not sync any other integration changes, but if we did, you can use this variable. +@receiver(process_control_outbox, sender=OutboxCategory.IDENTITY_UPDATE) +def process_identity_updates(object_identifier: int, region_name: str, **kwds: Any): + if ( + identity := maybe_process_tombstone(Identity, object_identifier, region_name=region_name) + ) is None: + return + identity.delete() + + @receiver(process_control_outbox, sender=OutboxCategory.SENTRY_APP_UPDATE) def process_sentry_app_updates(object_identifier: int, region_name: str, **kwds: Any): if ( diff --git a/src/sentry/users/models/identity.py b/src/sentry/users/models/identity.py index e5fb728b0725..b5fdb53f26bf 100644 --- a/src/sentry/users/models/identity.py +++ b/src/sentry/users/models/identity.py @@ -6,7 +6,7 @@ from django.conf import settings from django.contrib.postgres.fields.array import ArrayField -from django.db import IntegrityError, models +from django.db import IntegrityError, models, router, transaction from django.db.models import Q, QuerySet from django.utils import timezone @@ -19,7 +19,10 @@ control_silo_model, ) from sentry.db.models.manager.base import BaseManager +from sentry.hybridcloud.models.outbox import ControlOutbox, outbox_context +from sentry.hybridcloud.outbox.category import OutboxCategory, OutboxScope from sentry.integrations.types import ExternalProviders, IntegrationProviderSlug +from sentry.types.region import find_regions_for_user from sentry.users.services.user import RpcUser if TYPE_CHECKING: @@ -212,6 +215,19 @@ class Meta: db_table = "sentry_identity" unique_together = (("idp", "external_id"), ("idp", "user")) + def delete(self, *args: Any, **kwargs: Any) -> tuple[int, dict[str, int]]: + with outbox_context(transaction.atomic(router.db_for_write(Identity))): + region_names = find_regions_for_user(self.user_id) + for region_name in region_names: + ControlOutbox( + shard_scope=OutboxScope.USER_SCOPE, + shard_identifier=self.user_id, + object_identifier=self.id, + category=OutboxCategory.IDENTITY_UPDATE, + region_name=region_name, + ).save() + return super().delete(*args, **kwargs) + def get_provider(self) -> Provider: from sentry.identity import get diff --git a/tests/sentry/receivers/outbox/test_control.py b/tests/sentry/receivers/outbox/test_control.py index 65987f7cba0d..be88eab3955f 100644 --- a/tests/sentry/receivers/outbox/test_control.py +++ b/tests/sentry/receivers/outbox/test_control.py @@ -4,12 +4,14 @@ from sentry.models.apiapplication import ApiApplication from sentry.receivers.outbox.control import ( process_api_application_updates, + process_identity_updates, process_integration_updates, process_sentry_app_updates, ) from sentry.testutils.cases import TestCase from sentry.testutils.silo import control_silo_test from sentry.types.region import Region, RegionCategory +from sentry.users.models.identity import Identity _TEST_REGION = Region("eu", 1, "http://eu.testserver", RegionCategory.MULTI_TENANT) @@ -27,6 +29,13 @@ def test_process_integration_updates(self, mock_maybe_process: MagicMock) -> Non Integration, self.identifier, region_name=_TEST_REGION.name ) + @patch("sentry.receivers.outbox.control.maybe_process_tombstone") + def test_process_identity_updates(self, mock_maybe_process: MagicMock) -> None: + process_identity_updates(object_identifier=self.identifier, region_name=_TEST_REGION.name) + mock_maybe_process.assert_called_with( + Identity, self.identifier, region_name=_TEST_REGION.name + ) + @patch("sentry.receivers.outbox.control.maybe_process_tombstone") def test_process_api_application_updates(self, mock_maybe_process: MagicMock) -> None: process_api_application_updates( From 70bb7486811356620d6d2a0e39b9ffe66afcfbe7 Mon Sep 17 00:00:00 2001 From: Alex Sohn <44201357+alexsohn1126@users.noreply.github.com> Date: Fri, 2 Jan 2026 10:44:32 -0500 Subject: [PATCH 03/11] Update constants.py --- src/sentry/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/constants.py b/src/sentry/constants.py index 1eb43c02eddf..166aec6b1313 100644 --- a/src/sentry/constants.py +++ b/src/sentry/constants.py @@ -737,7 +737,7 @@ class InsightModules(Enum): INGEST_THROUGH_TRUSTED_RELAYS_ONLY_DEFAULT = "disabled" # Repository owner for console SDK repositories -CONSOLE_SDK_REPO_OWNER = "alexsohn1126" +CONSOLE_SDK_REPO_OWNER = "getsentry" # `sentry:events_member_admin` - controls whether the 'member' role gets the event:admin scope EVENTS_MEMBER_ADMIN_DEFAULT = True From a68ac5f6c600113283f7586057e0f3f0ad92650c Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Fri, 2 Jan 2026 13:16:14 -0500 Subject: [PATCH 04/11] changed defaults and added defaults for testing --- src/sentry/options/defaults.py | 28 +++++---------------------- src/sentry/testutils/pytest/sentry.py | 6 ++++++ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/sentry/options/defaults.py b/src/sentry/options/defaults.py index d27defd6e075..da0574f42867 100644 --- a/src/sentry/options/defaults.py +++ b/src/sentry/options/defaults.py @@ -699,31 +699,13 @@ register("github-app.client-secret", flags=FLAG_CREDENTIAL | FLAG_PRIORITIZE_DISK) # GitHub Console SDK App (separate app for repository invitations) +register("github-console-sdk-app.id", default=0, flags=FLAG_AUTOMATOR_MODIFIABLE) +register("github-console-sdk-app.client-id", default="", flags=FLAG_AUTOMATOR_MODIFIABLE) +register("github-console-sdk-app.installation-id", default="", flags=FLAG_CREDENTIAL) register( - "github-console-sdk-app.id", - default=0, - flags=FLAG_AUTOMATOR_MODIFIABLE | FLAG_ALLOW_EMPTY, -) -register( - "github-console-sdk-app.client-id", - default="", - flags=FLAG_AUTOMATOR_MODIFIABLE | FLAG_ALLOW_EMPTY, -) -register( - "github-console-sdk-app.installation-id", - default="", - flags=FLAG_CREDENTIAL | FLAG_ALLOW_EMPTY, -) -register( - "github-console-sdk-app.client-secret", - default="", - flags=FLAG_CREDENTIAL | FLAG_ALLOW_EMPTY, -) -register( - "github-console-sdk-app.private-key", - default="", - flags=FLAG_CREDENTIAL | FLAG_ALLOW_EMPTY, + "github-console-sdk-app.client-secret", flags=FLAG_PRIORITIZE_DISK | FLAG_AUTOMATOR_MODIFIABLE ) +register("github-console-sdk-app.private-key", flags=FLAG_CREDENTIAL | FLAG_PRIORITIZE_DISK) # Github Enterprise Integration register( diff --git a/src/sentry/testutils/pytest/sentry.py b/src/sentry/testutils/pytest/sentry.py index ce634747117e..17efbdc63588 100644 --- a/src/sentry/testutils/pytest/sentry.py +++ b/src/sentry/testutils/pytest/sentry.py @@ -217,6 +217,12 @@ def pytest_configure(config: pytest.Config) -> None: "github-app.name": "sentry-test-app", "github-app.client-id": "github-client-id", "github-app.client-secret": "github-client-secret", + "github-console-sdk-app.id": 42, + "github-console-sdk-app.name": "sentry-test-app", + "github-console-sdk-app.client-id": "github-client-id", + "github-console-sdk-app.client-secret": "github-client-secret", + "github-console-sdk-app.installation-id": "123123123", + "github-console-sdk-app.private-key": "github-private-key", "vsts.client-id": "vsts-client-id", "vsts.client-secret": "vsts-client-secret", "vsts-limited.client-id": "vsts-limited-client-id", From 19e7649aa279e67cdfdfb397512a45b851b6540e Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Fri, 2 Jan 2026 14:36:29 -0500 Subject: [PATCH 05/11] remove console-sdk-app name option --- src/sentry/testutils/pytest/sentry.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sentry/testutils/pytest/sentry.py b/src/sentry/testutils/pytest/sentry.py index 17efbdc63588..a75b1ebea938 100644 --- a/src/sentry/testutils/pytest/sentry.py +++ b/src/sentry/testutils/pytest/sentry.py @@ -218,7 +218,6 @@ def pytest_configure(config: pytest.Config) -> None: "github-app.client-id": "github-client-id", "github-app.client-secret": "github-client-secret", "github-console-sdk-app.id": 42, - "github-console-sdk-app.name": "sentry-test-app", "github-console-sdk-app.client-id": "github-client-id", "github-console-sdk-app.client-secret": "github-client-secret", "github-console-sdk-app.installation-id": "123123123", From f2cd3d6edfd3fb2e4a5d03941a65b8b0aa4f0d4f Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Fri, 2 Jan 2026 15:39:24 -0500 Subject: [PATCH 06/11] change ordering and flags for defaults --- src/sentry/options/defaults.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sentry/options/defaults.py b/src/sentry/options/defaults.py index cd92645147af..688900fa3de7 100644 --- a/src/sentry/options/defaults.py +++ b/src/sentry/options/defaults.py @@ -706,12 +706,10 @@ # GitHub Console SDK App (separate app for repository invitations) register("github-console-sdk-app.id", default=0, flags=FLAG_AUTOMATOR_MODIFIABLE) -register("github-console-sdk-app.client-id", default="", flags=FLAG_AUTOMATOR_MODIFIABLE) register("github-console-sdk-app.installation-id", default="", flags=FLAG_CREDENTIAL) -register( - "github-console-sdk-app.client-secret", flags=FLAG_PRIORITIZE_DISK | FLAG_AUTOMATOR_MODIFIABLE -) register("github-console-sdk-app.private-key", flags=FLAG_CREDENTIAL | FLAG_PRIORITIZE_DISK) +register("github-console-sdk-app.client-id", default="", flags=FLAG_AUTOMATOR_MODIFIABLE) +register("github-console-sdk-app.client-secret", flags=FLAG_CREDENTIAL | FLAG_PRIORITIZE_DISK) # Github Enterprise Integration register( From 9b6710949bec939d45f60d6061abb1d09f51a71b Mon Sep 17 00:00:00 2001 From: Alex Sohn <44201357+alexsohn1126@users.noreply.github.com> Date: Mon, 5 Jan 2026 09:37:15 -0500 Subject: [PATCH 07/11] Update src/sentry/constants.py Co-authored-by: Bruno Garcia --- src/sentry/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/constants.py b/src/sentry/constants.py index 166aec6b1313..0c30522b9838 100644 --- a/src/sentry/constants.py +++ b/src/sentry/constants.py @@ -736,7 +736,7 @@ class InsightModules(Enum): ENABLE_PR_REVIEW_TEST_GENERATION_DEFAULT = False INGEST_THROUGH_TRUSTED_RELAYS_ONLY_DEFAULT = "disabled" -# Repository owner for console SDK repositories +# Repository owner for console SDK repositories. Helpful for testing: add your test org here CONSOLE_SDK_REPO_OWNER = "getsentry" # `sentry:events_member_admin` - controls whether the 'member' role gets the event:admin scope From 9f01568dab795dd9895792b5bf41933673fde738 Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Mon, 5 Jan 2026 09:46:03 -0500 Subject: [PATCH 08/11] delete object deletion code in outbox processing --- src/sentry/receivers/outbox/control.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sentry/receivers/outbox/control.py b/src/sentry/receivers/outbox/control.py index 46d12b26583f..abbd6449d258 100644 --- a/src/sentry/receivers/outbox/control.py +++ b/src/sentry/receivers/outbox/control.py @@ -45,11 +45,7 @@ def process_integration_updates(object_identifier: int, region_name: str, **kwds @receiver(process_control_outbox, sender=OutboxCategory.IDENTITY_UPDATE) def process_identity_updates(object_identifier: int, region_name: str, **kwds: Any): - if ( - identity := maybe_process_tombstone(Identity, object_identifier, region_name=region_name) - ) is None: - return - identity.delete() + maybe_process_tombstone(Identity, object_identifier, region_name=region_name) @receiver(process_control_outbox, sender=OutboxCategory.SENTRY_APP_UPDATE) From d30be336399db3809403d21daee4537e17b1fb23 Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Mon, 5 Jan 2026 10:37:52 -0500 Subject: [PATCH 09/11] send identity update outbox to all regions --- src/sentry/users/models/identity.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sentry/users/models/identity.py b/src/sentry/users/models/identity.py index b5fdb53f26bf..ea3c81523064 100644 --- a/src/sentry/users/models/identity.py +++ b/src/sentry/users/models/identity.py @@ -22,7 +22,7 @@ from sentry.hybridcloud.models.outbox import ControlOutbox, outbox_context from sentry.hybridcloud.outbox.category import OutboxCategory, OutboxScope from sentry.integrations.types import ExternalProviders, IntegrationProviderSlug -from sentry.types.region import find_regions_for_user +from sentry.types.region import find_all_region_names from sentry.users.services.user import RpcUser if TYPE_CHECKING: @@ -217,7 +217,8 @@ class Meta: def delete(self, *args: Any, **kwargs: Any) -> tuple[int, dict[str, int]]: with outbox_context(transaction.atomic(router.db_for_write(Identity))): - region_names = find_regions_for_user(self.user_id) + # Fan out to all regions to ensure HybridCloudForeignKey cascade works even without org memberships + region_names = find_all_region_names() for region_name in region_names: ControlOutbox( shard_scope=OutboxScope.USER_SCOPE, From e6ce7c3d443e4368f689fc2064bb65e197da29f3 Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Mon, 5 Jan 2026 10:39:42 -0500 Subject: [PATCH 10/11] add api update for consolesdkinvitequota --- src/sentry/api/serializers/models/organization.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sentry/api/serializers/models/organization.py b/src/sentry/api/serializers/models/organization.py index 52b34576bbe9..983a2a9719b4 100644 --- a/src/sentry/api/serializers/models/organization.py +++ b/src/sentry/api/serializers/models/organization.py @@ -514,6 +514,7 @@ class _DetailedOrganizationSerializerResponseOptional(OrganizationSerializerResp desiredSampleRate: float ingestThroughTrustedRelaysOnly: bool enabledConsolePlatforms: list[str] + consoleSdkInviteQuota: int @extend_schema_serializer(exclude_fields=["availableRoles"]) @@ -811,6 +812,9 @@ def serialize( # type: ignore[override] ENABLED_CONSOLE_PLATFORMS_DEFAULT, ) + quota_limit = obj.get_option("sentry:console_sdk_invite_quota_limit", 1) + context["consoleSdkInviteQuota"] = quota_limit + if access.role is not None: context["role"] = access.role # Deprecated context["orgRole"] = access.role @@ -841,6 +845,7 @@ def serialize( # type: ignore[override] "streamlineOnly", "ingestThroughTrustedRelaysOnly", "enabledConsolePlatforms", + "consoleSdkInviteQuota", "hasGranularReplayPermissions", "replayAccessMembers", ] From a946acf1df9b5cede59497a2aca5dcdd5f933632 Mon Sep 17 00:00:00 2001 From: Alex Sohn Date: Mon, 5 Jan 2026 10:49:36 -0500 Subject: [PATCH 11/11] change quota limit to use default constant --- src/sentry/api/serializers/models/organization.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sentry/api/serializers/models/organization.py b/src/sentry/api/serializers/models/organization.py index 983a2a9719b4..3ace51043a1b 100644 --- a/src/sentry/api/serializers/models/organization.py +++ b/src/sentry/api/serializers/models/organization.py @@ -34,6 +34,7 @@ ATTACHMENTS_ROLE_DEFAULT, AUTO_ENABLE_CODE_REVIEW, AUTO_OPEN_PRS_DEFAULT, + CONSOLE_SDK_INVITE_QUOTA_DEFAULT, DATA_CONSENT_DEFAULT, DEBUG_FILES_ROLE_DEFAULT, DEFAULT_AUTOFIX_AUTOMATION_TUNING_DEFAULT, @@ -812,8 +813,10 @@ def serialize( # type: ignore[override] ENABLED_CONSOLE_PLATFORMS_DEFAULT, ) - quota_limit = obj.get_option("sentry:console_sdk_invite_quota_limit", 1) - context["consoleSdkInviteQuota"] = quota_limit + context["consoleSdkInviteQuota"] = obj.get_option( + "sentry:console_sdk_invite_quota_limit", + CONSOLE_SDK_INVITE_QUOTA_DEFAULT, + ) if access.role is not None: context["role"] = access.role # Deprecated