Remove sentry.properties secrets in favour of public values and an env-injected token - #23189
Remove sentry.properties secrets in favour of public values and an env-injected token#23189mokagio wants to merge 12 commits into
Conversation
`defaults.org`/`defaults.project` in `sentry.properties` aren't secrets — they're Sentry-public identifiers. `auth.token` is the only genuinely secret line, and it's CI-only (used to upload ProGuard mappings). The Sentry Gradle plugin extension only exposes a single global org/projectName/authToken (confirmed by decompiling sentry-android-gradle-plugin — no per-flavor DSL support), but WordPress and Jetpack need two different Sentry projects. Rather than collapsing everything into the DSL (which would lose that split), `sentry.properties` stays as the per-flavor resolution mechanism the plugin already supports (`src/wordpress/sentry.properties`, `src/jetpack/sentry.properties`) — just stripped of `auth.token` and committed in plaintext instead of encrypted via `.configure`. `authToken` alone moves to the DSL, sourced from `SENTRY_AUTH_TOKEN`, since that's the same for both flavors. Note: `sentry.properties` here never held the Sentry DSN (unlike pocket-casts-android) — that comes from `secrets.properties`' `wp.sentry_dsn`/`jp.sentry_dsn` via a separate prefixed-property mechanism, untouched by this change. Part of AINFRA-2715. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
`sentry.properties` no longer carries `auth.token` — the file is committed in plaintext now, and the token reaches CI through the Buildkite agent's environment hook. The lane kept reading the key from the file, so `auth_token` would have been `nil` on every release and beta upload. `defaults.org`/`defaults.project` still come from the file: they're public identifiers and per-flavor, so the Gradle DSL can't hold them. Part of AINFRA-2715. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`includeSourceContext` is on for CI builds too, producing `sentryUploadSourceBundle*` tasks that upload through sentry-cli and need the same token as the mapping upload. The guard only covered `uploadSentryProguardMappings*`, so a missing token surfaced as a sentry-cli error there instead of the named failure. Part of AINFRA-2715. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`fastlane/Fastfile` already defines `get_required_env`, and its own comment asks callers to use it instead of reading `ENV` directly. It's also how `wpios` and `wcios` pass this exact token to `sentry_upload_sourcemap`. Part of AINFRA-2715. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
|
|
| tasks.matching { | ||
| it.name.startsWith("uploadSentryProguardMappings") || it.name.startsWith("sentryUploadSourceBundle") | ||
| }.configureEach { | ||
| doFirst { | ||
| if (!sentryAuthToken.isPresent()) { | ||
| throw new GradleException( | ||
| "SENTRY_AUTH_TOKEN is not set. Export it to upload ProGuard mappings and source bundles." | ||
| ) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
It's likely that the Sentry CLI has decent error handling for a missing SENTRY_AUTH_TOKEN, but is seemed good to fail early here in a similar way as we fail in fastlane.
| "file": "android/WPAndroid/jetpack-sentry.properties", | ||
| "destination": "WordPress/src/jetpack/sentry.properties", | ||
| "encrypt": true | ||
| }, |
There was a problem hiding this comment.
Notice no sentry.properties entry was removed. I haven't followed up with the Git history but it seems likely to me that the file was there in the pre-Jetpack days and was not deleted at the time of the fork.
…r-of-public-values-and-env
There was a problem hiding this comment.
Pull request overview
This PR removes the Sentry auth token from per-flavor sentry.properties and shifts authentication to an environment-injected SENTRY_AUTH_TOKEN, keeping only public Sentry org/project identifiers in the repo. This aligns with reducing developer-machine secrets while preserving separate WordPress vs Jetpack Sentry projects.
Changes:
- Add plaintext, per-flavor
sentry.propertiescontaining onlydefaults.org/defaults.project. - Configure Gradle Sentry plugin to read
SENTRY_AUTH_TOKENfrom the environment and fail early for upload tasks when unset. - Update Fastlane Gutenberg sourcemap upload to use
SENTRY_AUTH_TOKENinstead of readingauth.tokenfrom properties; remove related.configure/ignore entries.
Reviewed changes
Copilot reviewed 7 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| WordPress/src/wordpress/sentry.properties | Adds public Sentry org/project identifiers for the WordPress flavor. |
| WordPress/src/jetpack/sentry.properties | Adds public Sentry org/project identifiers for the Jetpack flavor. |
| WordPress/build.gradle | Reads SENTRY_AUTH_TOKEN from env and wires it into Sentry Gradle uploads with a preflight check. |
| fastlane/lanes/build.rb | Switches sourcemap upload auth to use SENTRY_AUTH_TOKEN. |
| .gitignore | Stops ignoring sentry.properties so flavor files can be committed. |
| .configure-files/wordpress-sentry.properties.enc | Removes encrypted Sentry properties artifact from .configure flow. |
| .configure | Removes .configure entries that previously provisioned Sentry properties. |
| .aiexclude | Allows sentry.properties to be visible to AI tooling (no longer treated as secret). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| sentry_upload_sourcemap( | ||
| auth_token: sentry_token, | ||
| auth_token: get_required_env('SENTRY_AUTH_TOKEN'), | ||
| org_slug: org_slug, |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Matching on a name prefix couples the guard to a plugin-internal naming convention. A future `io.sentry.android.gradle` bump that renames either upload task would silently stop matching, dropping the guard exactly where it is needed. `SentryCliExecTask` is the base of every task that shells out to `sentry-cli` with the auth token, so it covers the ProGuard mapping and source bundle uploads in one match and turns a rename into a compile error. Normalising the blank check where the token is read also keeps the bound `authToken` from disagreeing with the guard. Keeps this repo aligned with the same guard in `pocket-casts-android` and `dayone-android`. Part of [AINFRA-2715](https://linear.app/a8c/issue/AINFRA-2715). --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…r-of-public-values-and-env
wzieba
left a comment
There was a problem hiding this comment.
Added a few comments about readability
| tasks.withType(SentryCliExecTask).configureEach { | ||
| doFirst { | ||
| if (sentryAuthToken == null) { | ||
| throw new GradleException( |
There was a problem hiding this comment.
Do we have to do this here and not on line 71? Is there any advantage to rely on SentryCliExecTask?
There was a problem hiding this comment.
ah okay, I think I know why: you don't want to validate when just configuring the build (so it's possible to run build without secrets) but only fail on missing token when someone calls a Sentry task, makes sense
Co-authored-by: Wojciech Zięba <wojciech.zieba@protonmail.com>
…r-of-public-values-and-env
…r-of-public-values-and-env


Pre-work to migrate from
configuretoa8c-secretsby only keeping those secrets that are actually needed. See https://linear.app/a8c/issue/AINFRA-2715.Notice this moves the Sentry token injection from dev-level secrets to CI-level secrets, via env var. This is in line with our approach of having as few secrets as possible on dev machines.
Verified by unblocking a Prototype Build, even though it only exercised the fastlane path, leaving the Gradle one unverified.
AI-generated details
defaults.organddefaults.projectinsentry.propertiesare public Sentry identifiers, not secrets.auth.tokenis the only genuinely secret line, and it's CI-only.So the per-app entries leave
.configure, the flavor files get committed in plaintext, and the token comes fromSENTRY_AUTH_TOKEN.Why
sentry.propertiesstays.The Sentry Gradle plugin's extension exposes a single global
org/projectName, but WordPress and Jetpack report to different Sentry projects.The per-flavor
sentry.propertieslookup is the only mechanism that preserves that split, so the files stay — stripped ofauth.token.Only
authTokenmoves to the DSL, since it's the same for both flavors.Where the token comes from.
SENTRY_AUTH_TOKENis injected by an agent-side environment hook on the Buildkiteandroidqueue.Nothing in this repo sets it, so grepping for it turns up nothing.
fastlane'supload_gutenberg_sourcemapswas readingauth.tokenout of the same file; it now usesget_required_env('SENTRY_AUTH_TOKEN').The Sentry DSN is untouched — it comes from
secrets.properties(wp.sentry_dsn/jp.sentry_dsn), not fromsentry.properties.Testing
Prototype builds run on every PR and exercise both upload paths, so this PR's own CI is the test.
uploadSentryProguardMappings…andsentryUploadSourceBundle…upload without a missing-token error.a8c/wordpress-androidanda8c/jetpack-android.Locally, with
SENTRY_AUTH_TOKENunset:CI=true ./gradlew :WordPress:uploadSentryProguardMappingsWordpressRelease.GradleException, not a sentry-cli error.