Synsema docsENES

Secretos

Un secret es un valor opaco y redactado: lo podés usar pero nunca leer su texto

plano desde el lenguaje. Es a prueba de LLMs por diseño — nunca aparece en print, logs,

cuerpos de error, respuestas JSON, el blackboard ni un prompt de LLM.

env() vs secret()

Ambos son deny-by-default: declarás la capacidad o la lectura falla.

secret-bearer.syn
-- Doc example (UNIVERSAL — one source, shared by every language).
-- Comments are English on purpose: the code is the same in /en, /es, /pt, ...
-- Doctest gate: `synsema test docs/0.4.x/examples/` must be green to publish.
intent: "doc example: a secret stays redacted everywhere except the socket"
require secret("API_KEY")

print("a secret prints as → " + text(secret("API_KEY", "sk-demo-123")))    -- redacted

test "a secret is redacted in every string surface"
    let k be secret("API_KEY", "sk-demo-123")
    assert_eq(text(k), "secret(API_KEY)")                       -- never the real value
    assert_eq(type_of(k), "secret")
    -- GOTCHA: concatenating text + secret yields a SECRET, and it redacts WHOLE —
    -- the "Authorization: " prefix is absorbed, you do NOT get "Authorization: secret(...)".
    assert_eq(type_of("Authorization: " + k), "secret")
    assert_eq(text("Authorization: " + k), "secret(API_KEY)")   -- prefix absorbed (taint)

test "bearer() builds a tainted Authorization value"
    let b be bearer(secret("API_KEY", "sk-demo-123"))
    assert_eq(type_of(b), "secret")                             -- still a secret
    assert_eq(text(b), "secret(API_KEY)")                       -- redacted, even as a Bearer value

test "a raw secret goes in ANY header, not just Bearer"
    -- materialization to the real value happens ONLY at the socket; here we just show
    -- it stays a redacted secret in your program's value space (see /docs/.../secrets).
    let headers be {"x-api-key": secret("API_KEY", "sk-demo-123")}
    assert_eq(text(headers["x-api-key"]), "secret(API_KEY)")

test "as_secret seals a value that arrives at runtime"
    let sealed be as_secret("rk-from-user", "user_key")         -- e.g. a tenant's key from a header
    assert_eq(text(sealed), "secret(user_key)")
    assert_eq(type_of(sealed), "secret")

Las credenciales van en cualquier header — no solo Bearer

Un secret puesto como valor de header se materializa a su valor real **solo en el

socket, sin importar el nombre del header. O sea que no** estás limitado a

Authorization:

En query params y el body un secret se redacta (fail-closed) — una credencial

solo sobrevive en el cable dentro de un header.

as_secret() — sellar un valor que llega en runtime

secret("NAME") lee del config. Para un valor que llega en runtime y no está en .env

(la key de un usuario en un header entrante, un token de otra llamada HTTP), sellalo en el

borde con as_secret(value, label?). Es puro (sin require), idempotente sobre un secret,

y acepta texto o bytes.

reveal() — el último recurso (auditado)

reveal(secret) devuelve el texto plano. Exige require reveal("NAME") **scopeado al

nombre/label del secret**, escribe una entrada de auditoría append-only por cada intento, y

avisa con un warning en la forma pelada (sin scope). Preferí bearer/hmac_sha256/

verify_hmac — consumen el secret sin exponerlo.