{"record":{"id":"e08f2643be129db8","repo":"neondatabase/neon","slug":"invalid-compute-claims-scope-s","errorCode":null,"errorMessage":"invalid compute claims scope \"{s}\"","messagePattern":"invalid compute claims scope \"(.+?)\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/compute_api/src/requests.rs","lineNumber":29,"sourceCode":"pub static COMPUTE_AUDIENCE: &str = \"compute\";\n\n/// Available scopes for a compute's JWT.\n#[derive(Copy, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum ComputeClaimsScope {\n    /// An admin-scoped token allows access to all of `compute_ctl`'s authorized\n    /// facilities.\n    #[serde(rename = \"compute_ctl:admin\")]\n    Admin,\n}\n\nimpl FromStr for ComputeClaimsScope {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        match s {\n            \"compute_ctl:admin\" => Ok(ComputeClaimsScope::Admin),\n            _ => Err(anyhow::anyhow!(\"invalid compute claims scope \\\"{s}\\\"\")),\n        }\n    }\n}\n\n/// When making requests to the `compute_ctl` external HTTP server, the client\n/// must specify a set of claims in `Authorization` header JWTs such that\n/// `compute_ctl` can authorize the request.\n#[derive(Clone, Debug, Deserialize, Serialize)]\n#[serde(rename = \"snake_case\")]\npub struct ComputeClaims {\n    /// The compute ID that will validate the token. The only case in which this\n    /// can be [`None`] is if [`Self::scope`] is\n    /// [`ComputeClaimsScope::Admin`].\n    pub compute_id: Option<String>,\n\n    /// The scope of what the token authorizes.\n    pub scope: Option<ComputeClaimsScope>,\n","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/libs/compute_api/src/requests.rs#L11-L47","documentation":"ComputeClaimsScope has exactly one variant, Admin, serialized as 'compute_ctl:admin'. Its FromStr impl accepts only that literal string; any other input — used when building or parsing JWT claims scopes for compute_ctl's external HTTP API — fails with this error.","triggerScenarios":"Code or config that parses a scope string into ComputeClaimsScope (e.g. when constructing ComputeClaims for an Authorization-header JWT or parsing a token's scope claim) with a value like 'admin', 'compute_ctl', or 'compute_ctl:Admin'. Only 'compute_ctl:admin' matches.","commonSituations":"Hand-writing JWT claims for compute_ctl APIs and guessing the scope format; changing the scope string during refactors and forgetting the serde rename; tooling that uppercases or trims the scope token.","solutions":["Use the exact string 'compute_ctl:admin' as the scope","In Rust code, avoid string literals entirely and use ComputeClaimsScope::Admin and its Serialize impl to emit the correct value","Check for whitespace/case damage if the scope travels through config or env vars"],"exampleFix":"// before\nlet scope: ComputeClaimsScope = \"admin\".parse()?;\n// after\nlet scope: ComputeClaimsScope = \"compute_ctl:admin\".parse()?;\n// or, better:\nlet scope = ComputeClaimsScope::Admin;","handlingStrategy":"type-guard","validationCode":"fn valid_scope(s: &str) -> bool {\n    s == serde_json::to_value(ComputeClaimsScope::Admin).unwrap()\n        .as_str().unwrap()\n}","typeGuard":"fn is_compute_claims_scope(s: &str) -> bool {\n    // single-variant enum: exactly one literal is valid\n    s == \"compute_ctl:admin\"\n}","tryCatchPattern":"match s.parse::<ComputeClaimsScope>() {\n    Ok(scope) => { /* build claims with scope */ }\n    Err(_) if !is_compute_claims_scope(s) => {\n        // reject early with the exact accepted literal instead of a generic parse error\n        return Err(format!(\"scope must be 'compute_ctl:admin', got '{s}'\"));\n    }\n    Err(e) => return Err(e.to_string()),\n}","preventionTips":["Never hardcode the scope string; use ComputeClaimsScope::Admin and serialize it","Keep scope round-trips through serde rather than manual string handling"],"tags":["compute-api","jwt","claims","scope","rust"],"backgroundTag":"invalid-token-scope","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}