{"openapi":"3.0.3","info":{"title":"Log Redact & Secret Scanner API","version":"1.0.0","description":"Detects and masks leaked API keys, cloud tokens, JWTs, private keys, database URLs, and high-entropy secrets in logs, .env files, and git diffs."},"servers":[{"url":"https://api.tinplate.dev","description":"Production Edge Gateway"}],"components":{"schemas":{"SecretScanResponseData":{"type":"object","properties":{"verdict":{"type":"string","enum":["allow","warn","block"],"example":"block"},"risk_score":{"type":"integer","minimum":0,"maximum":100,"example":95},"redacted_text":{"type":"string","example":"export GITHUB_TOKEN=[SECRET_GITHUB_TOKEN_1]\nDB_URL=[SECRET_BASIC_AUTH_URL_1]"},"findings":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["OPENAI_API_KEY","ANTHROPIC_API_KEY","HUGGINGFACE_TOKEN","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","GITHUB_TOKEN","GITLAB_TOKEN","SLACK_TOKEN","SLACK_WEBHOOK","STRIPE_KEY","GOOGLE_API_KEY","SENDGRID_API_KEY","TWILIO_API_KEY","MAILGUN_API_KEY","SHOPIFY_TOKEN","NPM_TOKEN","PYPI_TOKEN","DATABRICKS_TOKEN","DIGITALOCEAN_TOKEN","LINEAR_API_KEY","SUPABASE_TOKEN","POSTMAN_API_KEY","DISCORD_WEBHOOK","TELEGRAM_BOT_TOKEN","PRIVATE_KEY","JWT","BASIC_AUTH_URL","GENERIC_HIGH_ENTROPY"]},"severity":{"type":"string","enum":["critical","high","medium"]},"start":{"type":"integer","minimum":0},"end":{"type":"integer","minimum":0},"line":{"type":"integer","minimum":0,"exclusiveMinimum":true},"replacement":{"type":"string"},"entropy":{"type":"number"},"validated":{"type":"boolean"}},"required":["type","severity","start","end","line","replacement","entropy","validated"]}},"counts":{"type":"object","additionalProperties":{"type":"integer","minimum":0}},"total_secrets":{"type":"integer","minimum":0,"example":2},"tokens":{"type":"object","additionalProperties":{"type":"string"},"description":"Token-to-secret lookup map (populated only when mode === 'token', never persisted)."}},"required":["verdict","risk_score","redacted_text","findings","counts","total_secrets","tokens"]},"SecretScanRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":262144,"example":"export GITHUB_TOKEN=ghp_1234567890abcdefghijklmnopqrstuvwxyz\nDB_URL=postgres://admin:s3cr3tP@ssw0rd99@db.internal:5432/prod","description":"Raw log output, .env file, code snippet, or unified git diff to scan."},"mode":{"type":"string","enum":["token","mask","partial"],"default":"token","example":"token","description":"'token' replaces each unique secret with [SECRET_<TYPE>_<N>] and returns a caller-only map; 'mask' replaces with [REDACTED:<TYPE>]; 'partial' preserves a short prefix/suffix."},"types":{"type":"array","items":{"type":"string","enum":["OPENAI_API_KEY","ANTHROPIC_API_KEY","HUGGINGFACE_TOKEN","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","GITHUB_TOKEN","GITLAB_TOKEN","SLACK_TOKEN","SLACK_WEBHOOK","STRIPE_KEY","GOOGLE_API_KEY","SENDGRID_API_KEY","TWILIO_API_KEY","MAILGUN_API_KEY","SHOPIFY_TOKEN","NPM_TOKEN","PYPI_TOKEN","DATABRICKS_TOKEN","DIGITALOCEAN_TOKEN","LINEAR_API_KEY","SUPABASE_TOKEN","POSTMAN_API_KEY","DISCORD_WEBHOOK","TELEGRAM_BOT_TOKEN","PRIVATE_KEY","JWT","BASIC_AUTH_URL","GENERIC_HIGH_ENTROPY"]},"description":"Optional allowlist of secret types to scan for. Scans all 18 types when omitted."},"diff_only_added":{"type":"boolean","default":false,"example":false,"description":"When true on a unified git diff, ignores removed lines ('-...') and only scans added/context lines."},"min_entropy":{"type":"number","minimum":2.5,"maximum":6,"default":3.8,"example":3.8,"description":"Minimum Shannon entropy (bits/char) required for GENERIC_HIGH_ENTROPY matches."}},"required":["text"]},"SecretRestoreResponseData":{"type":"object","properties":{"restored_text":{"type":"string"},"replacements":{"type":"integer","minimum":0}},"required":["restored_text","replacements"]},"SecretRestoreRequest":{"type":"object","properties":{"redacted_text":{"type":"string","minLength":1,"maxLength":262144,"example":"export GITHUB_TOKEN=[SECRET_GITHUB_TOKEN_1]"},"tokens":{"type":"object","additionalProperties":{"type":"string"},"example":{"[SECRET_GITHUB_TOKEN_1]":"ghp_1234567890abcdefghijklmnopqrstuvwxyz"}}},"required":["redacted_text","tokens"]},"ResponseMeta":{"type":"object","required":["request_id"],"properties":{"request_id":{"type":"string","format":"uuid"},"ms":{"type":"integer","minimum":0},"version":{"type":"string","example":"1.0.0"}}},"ErrorEnvelope":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"invalid_input"},"message":{"type":"string","example":"Request body failed validation"}}},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}},"parameters":{}},"paths":{"/v1/secret-scanner":{"post":{"tags":["16_SECRET_SCANNER"],"summary":"Scan and mask leaked secrets in logs, text, or git diffs","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretScanRequest"}}}},"responses":{"200":{"description":"Scan verdict, structured secret findings, and redacted text","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/SecretScanResponseData"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"required":["ok","data","meta"]}}}},"400":{"description":"Invalid input or malformed JSON request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid authentication credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Request payload exceeds subscribed plan byte cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/secret-scanner/restore":{"post":{"tags":["16_SECRET_SCANNER"],"summary":"Statelessly restore [SECRET_*] tokens using caller-provided map","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretRestoreRequest"}}}},"responses":{"200":{"description":"Restored text and replacement count","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/SecretRestoreResponseData"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"required":["ok","data","meta"]}}}},"400":{"description":"Invalid input or malformed JSON request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid authentication credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Request payload exceeds subscribed plan byte cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}}}