Dashboard › cli › Distillation
fe0fafa8-1943-45f2-aca9-d108d7734254["lore_tm_v1_ltMOcozy1iBtI0iD6qG6TXDQ5li6I2wMeR0DzijA_XI","lore_tm_v1_Gyg5INwnZB-5UHdSlKSJpP-Fa1cgu5VL5l_norctWWc","lore_tm_v1_O2q3o6WI3zwfQawtlq1COjpGW8szkDEJ9UQuQy3xRX0","lore_tm_v1_WQ2xvQEQIWB4GfjDoadZhP-5a1V3qpEplB9YDFxG1j0","lore_tm_v1_y8nkKiHzMFxij7IByqDKqV5uTL3YhrvZIki8Yry79X4","lore_tm_v1_tgHxyQ2JWjSSW0ftTPOV_dqYzN6U_CwCBfL78w5X0v8","lore_tm_v1_1skzQ_iZat_pU4hX1eH-Bcw7xtyeuy4yQBXfAcXgU3g","lore_tm_v1__dzpmWGmWCC0p3njWDhudI6yhwcjk6tOHCR8iXcEeIM","lore_tm_v1_cBl2GrhRTljxGd-ddRT4pafkekrnZ1S-dmvAKlUKCtY","lore_tm_v1_1yj1vdptD3cRXqtV-W_pRWfX3TOjXo90oUIMJ3E7kwI","lore_tm_v1_KfgrUcX66nF0jTwiaYmHi9RT4dHkcbbj1ZT7ZteZSTs","lore_tm_v1_ftroGlMjB91g3TEZYBhCusvmYCcyzcxgHYK1lMX2pZk"]
Date: Sep 10, 2026
packages/cli/src/lib/db/auth.ts:92-109: getRawEnvToken() reads trimmed SENTRY_AUTH_TOKEN first, then trimmed SENTRY_TOKEN, and always returns the environment token if set—even when stored OAuth normally has priority. It is used by the HTTP layer to determine whether an env token was provided independently of whether it is active, and by the per-endpoint permission cache.getConfiguredSentryUrl() should remain limited to explicit configuration, while API/control base URLs should fall back to the active credential’s trusted host; this preserves stored-OAuth precedence and validates token claims through the existing origin normalizer.packages/cli/test/lib/security/sntrys-claim-mismatch.test.ts: a sntrys_ token claiming https://sentry.firsthost.com must be rejected for a request to env-configured https://sentry.secondhost.com; the token must never hit the wire, verified by no Authorization header containing secret-tail-for-test.sntrys_ claim-scoping regressions in packages/cli/test/lib/security/sntrys-claim-mismatch.test.ts: claim-matching requests to https://sentry.acme.com attach Bearer; with no explicit URL, claim http://localhost:8000 routes getApiBaseUrl() and request URL to http://localhost:8000/api/0/organizations/; registered trusted regional URL https://us.sentry.acme.com is permitted for a control-silo claim https://sentry.acme.com; opaque non-sntrys_ token sntryu_opaqueusertoken1234567890abcdef is unaffected by the claim check and relies on ordinary host scoping.packages/cli/test/lib/constants.test.ts coverage: normalizeUrl() returns undefined for undefined, empty, and whitespace-only input; trims whitespace; prepends https:// to bare hosts including ports; preserves http:///https:// protocol case, paths, and trailing slashes. getCliEnvironment() maps 0.0.0-dev/uninjected version to development, 0.24.0-dev.1740000000 and 1.0.0-dev.1700000000 to nightly, and stable versions 0.20.0, 1.0.0, and 0.23.0 to production.getConfiguredSentryUrl() tests: no SENTRY_HOST/SENTRY_URL yields undefined; SENTRY_HOST overrides SENTRY_URL; bare host values normalize; a sntrys_ token claim http://localhost:8000 is used when no URL is configured; explicit SENTRY_HOST=https://configured.example.com overrides claim https://claimed.example.com; local http://localhost:8000 is preserved.packages/cli/src/lib/db/auth.ts:386-436: setAuthToken(token, expiresIn?, newRefreshToken?, options?) chooses stored auth host in order: (1) explicit options.host, (2) existing auth row host to preserve refresh scope, (3) getConfiguredSentryUrl(), (4) DEFAULT_SENTRY_URL; the resulting host is always normalized to scheme://host[:port] using normalizeOrigin, defaulting to DEFAULT_SENTRY_URL if normalization fails. It upserts auth row fields id, token, refresh_token, expires_at, issued_at, updated_at, and host, then resets identity fingerprint, auth token, auth row, and stored-credentials caches.packages/cli/test/lib/db/auth.host.test.ts expectations: explicit host persists; https://SENTRY.Acme.com/ normalizes to https://sentry.acme.com; absent explicit host uses SENTRY_HOST=https://env-host.example.com, otherwise https://sentry.io; refresh-style setAuthToken() without options.host preserves existing https://sentry.acme.com scope.host=NULL is lazily backfilled from the boot-time captureEnvTokenHost() snapshot, not mutable current env; boot-time SENTRY_HOST=https://legacy-configured.example.com migrates to that origin, no env migrates to https://sentry.io, and a subsequent .sentryclirc shim setting SENTRY_URL=https://rc-sourced.example.com must not redirect migration from the boot snapshot.clearAuth() trust-state behavior: it clears identity-specific regional allow-list entries such as https://us.host-a.com but preserves the process-local login trust anchor https://sentry.host-a.com, because auth login --url <new-host> registers that anchor before handleExistingAuth() invokes clearAuth() and needs it for IAP custom headers during re-authentication; the next applyLoginUrl overwrites the anchor.packages/cli/src/lib/sentry-urls.ts: getSentryBaseUrl() currently resolves getConfiguredSentryUrl() ?? DEFAULT_SENTRY_URL; getOrgBaseUrl(orgSlug) uses subdomain routing only for SaaS and otherwise returns the base; isSentrySaasUrl() is hostname-only and intentionally accepts http://sentry.io and https://sentry.io:8443 for routing/test-harness decisions, whereas isSaaSTrustOrigin() requires https: and default port because plaintext http://sentry.io is never legitimate and a crafted plaintext URL must not inherit SaaS trust.packages/cli/src/lib/sentry-urls.ts: normalizeOrigin(input) returns canonical scheme://host[:port] only for parseable URL strings, URL, or Request, and rejects bare hostnames; normalizeUserInputToOrigin(input) first calls normalizeUrl() to permit bare user-supplied hostnames, then normalizes the parsed origin.useTestConfigDir() in packages/cli/test/helpers.ts:104-143 must always restore the previous SENTRY_CONFIG_DIR value and never delete it during teardown; deleting it causes cross-file failures when later module-level code or beforeEach reads undefined. preload.ts sets SENTRY_CONFIG_DIR, so savedConfigDir is expected to be defined and the helper intentionally omits a deletion branch.useEnvSandbox(keys) behavior in packages/cli/test/helpers.ts:145-164: it saves listed process.env values, clears each listed key before each test, and restores saved values verbatim afterward while deleting keys that were originally absent.