{"record":{"id":"58805af9f2394bf9","repo":"Hmbown/CodeWhale","slug":"refusing-oversized-xai-oauth-credential-payload","errorCode":null,"errorMessage":"refusing oversized xAI OAuth credential payload","messagePattern":"refusing oversized xAI OAuth credential payload","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/config/src/xai_credentials.rs","lineNumber":226,"sourceCode":"            })?;\n        if bytes.len() as u64 > XAI_OAUTH_FILE_LIMIT {\n            bail!(\n                \"Codewhale-owned xAI OAuth file {} exceeds the {} byte limit\",\n                crate::quote_os_path(&self.directory.join(name)),\n                XAI_OAUTH_FILE_LIMIT\n            );\n        }\n        String::from_utf8(bytes).map(Some).map_err(|_| {\n            anyhow::anyhow!(\n                \"Codewhale-owned xAI OAuth file {} is not valid UTF-8\",\n                crate::quote_os_path(&self.directory.join(name))\n            )\n        })\n    }\n\n    pub fn write(&self, name: &str, bytes: &[u8], allow_replace: bool) -> Result<()> {\n        validate_owned_auth_name(name)?;\n        anyhow::ensure!(\n            bytes.len() as u64 <= XAI_OAUTH_FILE_LIMIT,\n            \"refusing oversized xAI OAuth credential payload\"\n        );\n        self.write_owned_file(name, bytes, allow_replace)\n    }\n\n    pub fn remove(&self, name: &str) -> Result<bool> {\n        validate_owned_auth_name(name)?;\n        self.remove_raw(name)\n    }\n\n    pub fn clear_all(&self) -> Result<usize> {\n        let mut removed = 0;\n        for name in self.owned_auth_names()? {\n            if self.remove(&name)? {\n                removed += 1;\n            }\n        }","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/config/src/xai_credentials.rs#L208-L244","documentation":"XaiOAuthCredentialStore::write enforces XAI_OAUTH_FILE_LIMIT (1 MiB, 1024*1024) on any credential payload before writing, refusing oversized writes so credential files stay small, parseable, and cannot be abused as a data dump. The check mirrors the read-side limit applied in the reader.","triggerScenarios":"Writing an OAuth document whose byte length exceeds 1,048,576: a token response embedding large JWK sets or certificates, a bug double-encoding JSON inside JSON, or a caller trying to store unrelated data through this API.","commonSituations":"Custom enterprise OAuth servers with very large id_token or claim sets; accidental serialization of the whole credential store into a single entry; tooling using the OAuth directory as scratch storage.","solutions":["Shrink the payload: persist only the required token fields, not embedded certificates or the full response envelope","Check for double-encoding bugs such as applying serde_json::to_string twice","If a legitimate OAuth payload must exceed 1 MiB, file an issue; XAI_OAUTH_FILE_LIMIT is the single knob"],"exampleFix":"// before: storing the entire discovery document alongside the token\nstore.write(\"token.json\", &serde_json::to_vec(&full_discovery_and_token)?)?;\n\n// after: persist only the token response\nstore.write(\"token.json\", &serde_json::to_vec(&token_response)?)?;","handlingStrategy":"validation","validationCode":"// Mirror the store's limit before writing:\nconst XAI_OAUTH_FILE_LIMIT: u64 = 1024 * 1024;\nfn oauth_payload_fits(bytes: &[u8]) -> bool {\n    bytes.len() as u64 <= XAI_OAUTH_FILE_LIMIT\n}","typeGuard":null,"tryCatchPattern":"On Err, shrink the payload (drop embedded certs or envelopes) and retry once; do not chunk or split the file, since the store expects one coherent document per name.","preventionTips":["Persist only the token response fields, not the full discovery document or response envelope","Audit for double-encoding (JSON serialized inside JSON) when OAuth payloads grow unexpectedly"],"tags":["xai","oauth","size-limit","validation"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}