Skip to content

Commit 14814e5

Browse files
authored
feat: apitoken types to support prefixes (#65684)
In support of getsentry/rfcs#32. Add a nullable `token_type` column to the `ApiToken` model. This will be used to help us identify the different kinds of API tokens we have in the application via a prefix. With this, we'll be able to integrate with GitHub and others' secret scanning program to prevent token leaks. Legacy (e.g. tokens that already exist) will have a null value here, so we'll know they are not one of our new tokens with the prefix format once all tokens are stored solely as hashed values.
1 parent bad358c commit 14814e5

5 files changed

Lines changed: 360 additions & 308 deletions

File tree

migrations_lockfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ feedback: 0004_index_together
99
hybridcloud: 0011_add_hybridcloudapitoken_index
1010
nodestore: 0002_nodestore_no_dictfield
1111
replays: 0004_index_together
12-
sentry: 0652_alert_rule_activation_condition
12+
sentry: 0653_apitoken_add_token_type
1313
social_auth: 0002_default_auto_field
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Generated by Django 5.0.2 on 2024-02-23 04:05
2+
3+
from django.db import migrations, models
4+
5+
from sentry.new_migrations.migrations import CheckedMigration
6+
7+
8+
class Migration(CheckedMigration):
9+
# This flag is used to mark that a migration shouldn't be automatically run in production. For
10+
# the most part, this should only be used for operations where it's safe to run the migration
11+
# after your code has deployed. So this should not be used for most operations that alter the
12+
# schema of a table.
13+
# Here are some things that make sense to mark as dangerous:
14+
# - Large data migrations. Typically we want these to be run manually by ops so that they can
15+
# be monitored and not block the deploy for a long period of time while they run.
16+
# - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to
17+
# have ops run this and not block the deploy. Note that while adding an index is a schema
18+
# change, it's completely safe to run the operation after the code has deployed.
19+
is_dangerous = False
20+
21+
dependencies = [
22+
("sentry", "0652_alert_rule_activation_condition"),
23+
]
24+
25+
operations = [
26+
migrations.AddField(
27+
model_name="apitoken",
28+
name="token_type",
29+
field=models.CharField(max_length=7, null=True),
30+
),
31+
]

src/sentry/models/apitoken.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from sentry.models.apiscopes import HasApiScopes
2020
from sentry.models.outbox import OutboxCategory
2121
from sentry.types.region import find_all_region_names
22+
from sentry.types.token import AuthTokenType
2223

2324
DEFAULT_EXPIRATION = timedelta(days=30)
2425

@@ -42,6 +43,7 @@ class ApiToken(ReplicatedControlModel, HasApiScopes):
4243
name = models.CharField(max_length=255, null=True)
4344
token = models.CharField(max_length=64, unique=True, default=generate_token)
4445
hashed_token = models.CharField(max_length=128, null=True)
46+
token_type = models.CharField(max_length=7, choices=AuthTokenType, null=True)
4547
token_last_characters = models.CharField(max_length=4, null=True)
4648
refresh_token = models.CharField(max_length=64, unique=True, null=True, default=generate_token)
4749
hashed_refresh_token = models.CharField(max_length=128, null=True)

src/sentry/types/token.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from django.db import models
2+
3+
4+
class AuthTokenType(models.TextChoices):
5+
"""
6+
Represents the various API/auth token types in the Sentry code base.
7+
The values equate to the expected prefix of each of the token types.
8+
"""
9+
10+
USER = "sntryu_"
11+
ORG = "sntrys_"
12+
USER_APP = "sntrya_"
13+
INTEGRATION = "sntryi_"
14+
15+
# tokens created prior to our prefixing
16+
__empty__ = None

0 commit comments

Comments
 (0)