Opaque secret container for credentials, keys, and other sensitive values.
Carry sensitive values through the system without leaking them via
logs, REPL output, exception traces, pretty-printers, or accidental
stdout. Unwrapping requires an explicit expose call — auditable,
greppable, intentional.
Secret is a deftype (not defrecord) — it is intentionally NOT a map.
Keyword lookup ((:value s)), get, and map destructuring all return
nil. The underlying field is reachable only via Java interop
((.value s)), which is greppable and easy to ban via lint.
expose — the ONE blessed unwrap. Every call site is a leak risk.(.value <Secret>) — interop escape hatch; ban in lint.Registered for print-method, print-dup, and clojure.pprint/simple-dispatch.
toString overrides Object — covers exception messages, log lines.
Hash is constant (0); equality is constant-time. Never serializable.
Opaque secret container for credentials, keys, and other sensitive values. ## Purpose Carry sensitive values through the system without leaking them via logs, REPL output, exception traces, pretty-printers, or accidental stdout. Unwrapping requires an explicit `expose` call — auditable, greppable, intentional. ## Type `Secret` is a deftype (not defrecord) — it is intentionally NOT a map. Keyword lookup (`(:value s)`), `get`, and map destructuring all return nil. The underlying field is reachable only via Java interop (`(.value s)`), which is greppable and easy to ban via lint. ## Audit surface - `expose` — the ONE blessed unwrap. Every call site is a leak risk. - `(.value <Secret>)` — interop escape hatch; ban in lint. ## Print safety Registered for `print-method`, `print-dup`, and `clojure.pprint/simple-dispatch`. `toString` overrides Object — covers exception messages, log lines. Hash is constant (0); equality is constant-time. Never serializable. ## Non-goals (v1) - Secure memory wiping. JVM strings cannot be reliably zeroed; this would be theater for SSH-pass / API-token use cases. Use char[] wrappers if you need defense against heap dumps. - Encryption at rest. This wraps live values in memory, not storage.
Opaque carrier for sensitive values.
Opaque carrier for sensitive values.
(expose s)Unwrap the secret value. AUDIT: every call site is a leak risk. Prefer scoping unwrap to the smallest possible block.
Unwrap the secret value. AUDIT: every call site is a leak risk. Prefer scoping unwrap to the smallest possible block.
(secret-key s)Return the lookup key (e.g. "vps/r1/root"). Non-sensitive — safe to log. May be nil for unkeyed secrets.
Return the lookup key (e.g. "vps/r1/root"). Non-sensitive — safe to log. May be nil for unkeyed secrets.
(secret-source s)Return the source label (e.g. :pass, :env, :keyfile, :literal). Non-sensitive — safe to log.
Return the source label (e.g. :pass, :env, :keyfile, :literal). Non-sensitive — safe to log.
(make-secret value source)(make-secret value source key)Wrap a raw value in a Secret.
value — the sensitive value (typically a String) source — label for the source (:pass, :env, :keyfile, :literal, etc.) key — the lookup key used to retrieve it (e.g. "vps/r1/root"), or nil if not applicable.
Returns a Secret instance.
Wrap a raw value in a Secret.
value — the sensitive value (typically a String)
source — label for the source (:pass, :env, :keyfile, :literal, etc.)
key — the lookup key used to retrieve it (e.g. "vps/r1/root"),
or nil if not applicable.
Returns a Secret instance.(secret? x)Truthy if x is an ISecret instance.
Truthy if x is an ISecret instance.
(with-secret [binding secret] & body)Bind the unwrapped value of secret to binding for the duration of
body. Encourages narrow unwrap scope.
(with-secret [pwd my-secret] (do-something-with pwd))
Bind the unwrapped value of `secret` to `binding` for the duration of `body`. Encourages narrow unwrap scope. (with-secret [pwd my-secret] (do-something-with pwd))
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |