Repository navigation
Conversation
… Identity is down Once SIGNER_CLAIM_REQUIRED_AFTER is set, every claimless token issued after it needs the license lookup, including every mobile user's token exchange. An Identity outage then refused all of them with 503. The cutoff only backstops a dex path that forgets the claim, so a failed lookup now counts as error and lets the request through. Tokens that carry signer_address still fail closed.
|
Final review change (9d1a6d8): with |
The cutoff only backstopped a hypothetical dex path that forgets the claim, and once set it made every claimless token exchange, every DIMO Mobile user's included, look up Identity. Tokens without signer_address are now never checked, with no Identity lookup. This also removes the fail-open handling of lookup errors added in 9d1a6d8: tokens that carry signer_address still fail closed.
|
Superseding my earlier comment: |
Timeout bounds each of the two calls a cold check makes in turn (Identity, then isSigner), so at 3 s a slow check could run about 6 s and outlast the 5-second deadline that vehicle-triggers-api and tesla-oracle set, turning into a 503 in enforce mode. At 2 s the worst case is 4 s. A test pins 2*Timeout below signercheck.GRPCTimeout.
A failed check (Identity or chain unreachable, timeout) went back to the caller as codes.Unavailable with nothing in token-exchange-api's logs. Log it at warn with the license, the signer and the error.
credit-tracker isn't part of this rollout, so it is no longer listed as a SignerCheck caller or a rollback step. prometheus-operator's own service target label wins at scrape time, which renames the app's service label to exported_service; the README now says so and filters on it.
Why
Disabling a license signer (API key) stops dex from minting new developer JWTs with it, but tokens it already minted keep exchanging for vehicle JWTs for their full 336 hours. The console's team feature needs a removed member cut off within about 10 minutes, the vehicle JWT lifetime. dex now stamps the signer on developer JWTs as
signer_address(DIMO-Network/dex#332).What
/v1/tokens/exchange: checks every token withsigner_addresswhoseethereum_addressis a developer license (Identity), whatever its audience.auddimo-driver) skipped the dev-license middleware, and the grant usesethereum_address, so an audience-based check could be bypassed.403 signer no longer authorized for this license.503 could not verify signer.licensesigner.Checker: Identity lookup, thenisSigner(signer)on the license account (new abigen binding).SignerCheck(license, signer) → is_signer: shares that cache. It answers true for non-licenses,InvalidArgumentfor non-hex input, andUnavailableon errors.pkg/signercheck: shared by vehicle-triggers-api, tesla-oracle and credit-tracker. It holdsSIGNER_CHECK_MODE(enforce|log|off), thesigner_check_total{service,result}metric, the Fiber middleware, and aSignerCheckclient with a 5 s deadline.SIGNER_CHECK_MODE: login dev and prod values; production switches toenforceafter a week.SignerCheckErrors(error above 1% of non-skipped checks, allowed + denied + error, over 5 min) as a PrometheusRule.Effect on existing developers
In
enforcemode, disabling an API key ends its tokens within about a minute instead of two weeks.Successor services
dauthandvtaren't live. If either ships, it needs the same check (usepkg/signercheck).Tests
pkg/signercheck: every mode and result, claimless tokens skipped without a check, malformed claims, metric counts, gRPC client with timeout.licensesigner: call shape, TTL for both answers, not-a-license cached, errors not cached, keyed, bounded, 3 s timeout, singleflight.TestSignerCheckOnExchange: mobile-audience token for a license is checked; for a non-license it passes.TestSignerCheck(gRPC).make generateis clean.Merge order
Merge after DIMO-Network/dex#332. Merging deploys to dev in
logmode, which refuses nothing. vehicle-triggers-api, tesla-oracle and credit-tracker importpkg/signercheckfrom this branch until it merges.