You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 40db1a5
Browse filesBrowse the repository at this point in the historyBrowse files
ci(decision-model-lint): Split the audit rule into narrow checks
Replace the broad auth-change audit rule with four narrow rules for
secret rotation, token issuance and revocation, privilege grants, and
account identity changes. In a whole-codebase run, about 87% of the
narrow rules' findings were real, versus about 23% for the broad rule.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: decisionModelLinter.config.ts
+63-9Lines changed: 63 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -118,25 +118,79 @@ const audit = {
118
118
'src/sentry/web/frontend/debug/**',
119
119
],
120
120
rules: {
121
-
authChangeAuditTrail: {
121
+
rotatesSecretWithoutRecord: {
122
122
prompt:
123
-
'Does the code change authentication or access state, and if so, does it record the change with create_audit_entry, create_audit_entry_from_user, create_system_audit_entry, log_service.record_audit_log, or capture_security_activity?',
123
+
'Does the code replace an existing client secret, signing secret, or webhook token with a new value at a user\'s request, such as rotating ApiApplication.client_secret or regenerating a project token? Generating a secret while installing an integration or creating a webhook subscription does not count. If so, does the same file record it with create_audit_entry, create_audit_entry_from_user, create_system_audit_entry, log_service.record_audit_log, capture_security_activity, or a sentry.audit logger (logging.getLogger("sentry.audit..."))?',
124
124
values: [
125
125
{
126
-
value: 'UNAUDITED',
126
+
value: 'TRUE',
127
+
description:
128
+
'The code assigns or updates a secret field with a newly generated value. Nothing in the file records it.',
129
+
severity: 'warn',
130
+
report:
131
+
'Record this change: org-level changes with create_audit_entry and an event from sentry/audit_log/register.py, user-level changes with capture_security_activity. If a function this code calls already records it, say so in the PR.',
132
+
},
133
+
{
134
+
value: 'FALSE',
135
+
description:
136
+
'No secret field gets a new value. Reading or comparing a secret does not count. Or the file records it.',
137
+
},
138
+
],
139
+
},
140
+
issuesOrRevokesTokenWithoutRecord: {
141
+
prompt:
142
+
'Outside the OAuth flows for third-party apps (ApiGrant, ApiAuthorization, the authorize, consent, token, and authorizations endpoints, and Sentry App token exchange or refresh), does the code create, revoke, deactivate, or change the scopes of an ApiToken, OrgAuthToken, ApiKey, SentryAppInstallationToken, or an agent token grant? Authenticating a request with a token does not count. If so, does the same file record it with create_audit_entry, create_audit_entry_from_user, create_system_audit_entry, log_service.record_audit_log, capture_security_activity, or a sentry.audit logger (logging.getLogger("sentry.audit..."))?',
143
+
values: [
144
+
{
145
+
value: 'TRUE',
127
146
description:
128
-
'The code creates, updates, or deletes auth state and nothing in the file records that action. Auth state is: member roles, team roles, invites, or adding and removing members; AuthProvider or SSO config; linking or unlinking an AuthIdentity; creating, rotating, or revoking an ApiToken, ApiKey, OrgAuthToken, or SentryAppInstallationToken; rotating a Sentry App client secret; 2FA authenticators; password, email, or primary email; superuser or staff grants; and org settings that require 2FA or email verification.',
147
+
'The code calls create, delete, or update on one of those token models (for example ApiToken.objects.create, token.delete(), update(date_deactivated=...), or update(scope_list=...)), or calls a function whose name says it grants token scopes (for example create_write_grant). Nothing in the file records it.',
129
148
severity: 'warn',
130
149
report:
131
-
'This changes auth or access state without recording it. Record org changes with create_audit_entry and an event from sentry/audit_log/register.py, and user changes such as password, email, or 2FA with capture_security_activity. If a helper this code calls already records it, say so in the PR.',
150
+
'Record this change: org-level changes with create_audit_entry and an event from sentry/audit_log/register.py, user-level changes with capture_security_activity. If a function this code calls already records it, say so in the PR.',
132
151
},
133
152
{
134
-
value: 'AUDITED',
135
-
description: 'The code changes auth state and the file records it.',
153
+
value: 'FALSE',
154
+
description:
155
+
'No such token is created, revoked, or rescoped. Authenticating with a token, updating last_used or date_last_used, and the OAuth authorize, consent, and token flows for third-party apps do not count. Or the file records it.',
136
156
},
157
+
],
158
+
},
159
+
changesPrivilegeWithoutRecord: {
160
+
prompt:
161
+
'Does the code grant or remove is_superuser, is_staff, or a UserPermission for a user? Organization and team roles are not privileges here. If so, does the same file record it with create_audit_entry, create_audit_entry_from_user, create_system_audit_entry, log_service.record_audit_log, capture_security_activity, or a sentry.audit logger (logging.getLogger("sentry.audit..."))?',
162
+
values: [
137
163
{
138
-
value: 'NOT_AUTH',
139
-
description: 'The code does not change auth or access state.',
164
+
value: 'TRUE',
165
+
description:
166
+
'The code sets is_superuser or is_staff on a User, or creates or deletes a UserPermission, and no audit_logger.info(...) call on a sentry.audit logger follows it. Judge each separately: if is_superuser or is_staff changes and only the UserPermission change is recorded, answer TRUE. Nothing in the file records it.',
167
+
severity: 'warn',
168
+
report:
169
+
'Record this change: org-level changes with create_audit_entry and an event from sentry/audit_log/register.py, user-level changes with capture_security_activity. If a function this code calls already records it, say so in the PR.',
170
+
},
171
+
{
172
+
value: 'FALSE',
173
+
description:
174
+
'No privilege flag or UserPermission changes. Starting or ending a superuser or staff session, and checking whether a user has a privilege, do not count. Or the file records it.',
175
+
},
176
+
],
177
+
},
178
+
changesAccountIdentityWithoutRecord: {
179
+
prompt:
180
+
'Does the code change a user\'s email or primary email, unlink or delete an AuthIdentity, or merge or delete user accounts? If so, does the same file record it with create_audit_entry, create_audit_entry_from_user, create_system_audit_entry, log_service.record_audit_log, capture_security_activity, or a sentry.audit logger (logging.getLogger("sentry.audit..."))?',
181
+
values: [
182
+
{
183
+
value: 'TRUE',
184
+
description:
185
+
'The code updates User.email or a UserEmail of an existing user, deletes an AuthIdentity, or merges or deletes User records. Setting the email of a new account being registered does not count. Nothing in the file records it.',
186
+
severity: 'warn',
187
+
report:
188
+
'Record this change: org-level changes with create_audit_entry and an event from sentry/audit_log/register.py, user-level changes with capture_security_activity. If a function this code calls already records it, say so in the PR.',
189
+
},
190
+
{
191
+
value: 'FALSE',
192
+
description:
193
+
'None of those change. Linking an identity through SSO setup, integration Identity links (Slack, MS Teams, Discord), verifying an email, and logging in do not count. Or the file records it.',
0 commit comments