Loading...
Loading...
Finds secrets, tokens, passwords, and API keys that can leak through generated serialization: Python dataclass repr and asdict, attrs, pydantic model_dump, NamedTuple, JavaScript JSON.stringify and util.inspect, structured logs, tracing spans, and error reports. Use when asked to "check for secret serialization", "credential in repr", "repr=False audit", "secret in spans", "token in logs", or when a change adds a credential field to a dataclass, model, or config object, or adds code that stringifies whole objects or every kwarg into telemetry.
npx skill4agent add getsentry/skills secret-serializationreprstrasdictmodel_dumptoJSONstr(value)span.set_data(key, obj)logger.info("%s", obj)JSON.stringify(args)security-review.env| Reference | Read When |
|---|---|
| Reviewing Python dataclasses, attrs, pydantic, NamedTuple, msgspec, logging, Sentry SDK, or OpenTelemetry code |
| Reviewing JavaScript or TypeScript classes, config objects, |
secrettokenpasswordpasswdpwdapi_keyapikeyaccess_keyprivate_keysigning_keyclient_secretbearercredentialauthorizationauth_headercookiesession_keydsnconnection_stringwebhook_secrethmacrefresh_tokenSecretStrSecretBytes__repr____str__asdictmodel_dumptoJSONJSON.stringifyutil.inspectvars(obj)obj.__dict__picklejson.dumps(obj, default=vars)| Mechanism | Blocks | Still includes the field |
|---|---|---|
| | |
Pydantic | | |
Pydantic | | |
Pydantic | Every generated path | Raw access |
JavaScript | Every generated path | Nothing outside the class body |
| Every generated path | Explicit property reads, |
Hand-written | Only the path it overrides (a | Every other generated path, raw access |
Redacting wrapper: | Every generated path | |
| Not stored on the object: read inside the method, or held in a closure | Everything | Nothing |
private__slots__dataclass(init=False)__init__**kwargsstr(value)repr(asdict(model_dump(set_data(set_attribute(set_context(set_extra(JSON.stringify(util.inspect(vars(__dict__pickle.dumps(default=vars| Category | Report When |
|---|---|
| Unexcluded credential field | A credential field is added or moved onto a type with generated serialization, and no mechanism blocks any of its generated paths. |
| Partial exclusion | At least one generated path still includes the field, and a sink in the repository uses that path on instances of the type. |
| Raw attribute sink | A sink applies |
| Credential moved onto a holder | A refactor moves a credential from a lazy read or closure onto an object field. |
| Wholesale serialization sink | New or changed telemetry, logging, error-context, cache, or response code serializes every kwarg, every attribute, or whole objects without an allowlist or redaction. |
| Sink loses its filter | A change removes or weakens redaction, an allowlist, or object-to-type-name replacement in an existing sink. |
| Object passed to telemetry | A client, config, or settings object is passed to a span, log, or error-context call that stringifies it. |
| Level | Use For |
|---|---|
| high | The credential reaches a sink anywhere in the repository: log line, span attribute, error event, cache entry, persisted row, queue payload, or API response. The other side may predate the diff. Also a new wholesale sink whose existing callers pass credential-bearing objects. |
| medium | An unexcluded credential field whose instances leave the constructing module, after a repository search found no sink. Also a wholesale sink with no allowlist and no traced credential-bearing caller. |
| low | An unexcluded credential field whose instances never leave the constructing scope. |
__dict__type(value).__name__str(value)sentry_sdk.serializer.serializejson.dumps(asdict(obj))JSON.stringify(obj)util.inspect(obj)_shared_secretRpcClient