#6591·zod

Add z.secret() / z.secretString() to redact sensitive parsed values in logs

Author: egomezsalasvaCreated Sep 11, 2026Updated Sep 15, 2026

It would be good to be able to guardrail sensitive fields from appearing in the logs and trace errors. For this reason I propose adding a z.secret() and potentially a z.secretString(). These values get Zod validation but add a protection layer so they do not directly appear in logs.

When parse fails, Zod already omits the raw value from issues unless you pass reportInput: true. When parse succeeds, the value is a normal string, so console.log, traces, and JSON.stringify still print it.

typescript
const Login = z.object({
  email: z.email(),
  password: z.string(),
  customerPII: z.object({
    passportNumber: z.string(),
    address: z.string(),
  }),
});

const user = Login.parse({
  email: "[email protected]",
  password: "secretPassword",
  customerPII: {
    passportNumber: "sensitivePassportNumber",
    address: "sensitiveCustomerLocation",
  },
});

console.log(user);

console.log(user) prints password and the whole customerPII object in the clear. The idea would be to mark those fields:

typescript
const Login = z.object({
  email: z.email(),
  password: z.secretString(),
  customerPII: z.secret(
    z.object({
      passportNumber: z.string(),
      address: z.string(),
    }),
  ),
});

z.secretString() is shorthand for z.secret(z.string()). z.secret() wraps any schema, so it can cover a nested object like customerPII. Extra checks stay on the inner schema, e.g. z.secret(z.string().min(8)).

Logging user would redact those fields. Validation stays the same.