> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automate.ax/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Automate.ax automations are TypeScript programs.
> Use Bun for installation and command examples.
> Use Automate.ax for the product name and automate.ax for the package, CLI, and domain.
> Treat documented public APIs as current; do not invent transitional or deprecated names.

# Protect sensitive values

> Protect selected action results, emitted data, and logs from execution history and local datasets.

Mark values as sensitive at the API that stores them. Automate.ax keeps the exact value encrypted for trusted runtime computation and writes only a redacted structural projection to run details, synchronized execution data, logs, and local SQL datasets.

## Protect an action result

Pass `sensitive: true` to protect the complete result, or pass a structural mask that mirrors the output type:

```ts theme={null}
import { defineAction } from "automate.ax"
import { z } from "zod"

const issueProtectedToken = defineAction("Issue protected token")
  .input(z.object({ itemId: z.string() }))
  .output(
    z.object({
      itemId: z.string(),
      token: z.string(),
    }),
    {
      sensitive: {
        token: true,
      },
    },
  )
  .retry({ replaySafety: "safe" })
  .handler(({ input }) => ({
    itemId: input.itemId,
    token: crypto.randomUUID(),
  }))
```

`true` protects one complete nested value. An object mask selects named properties. A one-element array mask applies to every array item. Properties omitted from the mask remain visible and available to queries.

Property signals preserve the matching part of the mask. An arbitrary `transform` that reads any sensitive signal produces a wholly sensitive value because Automate.ax can't prove which information the callback retained. Actions are explicit boundaries: sensitive inputs don't automatically make an action result sensitive. Add a sensitivity policy to that action's `.output()` when its returned value must remain protected.

Sensitive signals can't be coordinator partition keys. Project a non-sensitive property before `keyBy`, or choose another public correlation key.

## Protect emitted outputs and logs

Use the same explicit mask for emitted data. Logs accept a `sensitive` property covering their stored message and structured fields:

```ts theme={null}
import { defineAction } from "automate.ax"
import { z } from "zod"

const recordProtectedToken = defineAction("Record protected token")
  .input(z.object({ itemId: z.string() }))
  .retry({ replaySafety: "safe" })
  .handler(async ({ input, runtime }) => {
    const token = crypto.randomUUID()

    await runtime.sendOutput(
      {
        data: { itemId: input.itemId, token },
        type: "issued-token",
      },
      { sensitive: { token: true } },
    )

    await runtime.log({
      fields: { itemId: input.itemId, token },
      level: "info",
      message: `Issued ${token}`,
      sensitive: { fields: { token: true }, message: true },
    })
  })
```

Sensitivity is declaration-based. Automate.ax doesn't guess from property names or scan strings for known secret text. Don't place a secret in another output, message, field, or error unless that storage API supports a matching sensitivity declaration.

Automate.ax doesn't provide a decrypted reveal operation in run details or local execution datasets.
