Safeguard
Security Guides•

Prefect blocks or variables: where should a secret go?

Prefect blocks have typed fields, and SecretStr fields get extra encryption and are hidden in the UI. Variables are plain JSON. Use blocks for secrets.

Safeguard Security Team
3 min read

Put secrets in Prefect blocks, not variables. The Prefect docs draw a clear line. Variables are unstructured JSON documents, while block schemas can have SecretStr fields, which are stored with additional encryption and not displayed by default in the UI.

The distinction in plain terms

A block is a typed, saved configuration object: a schema with named fields. A block document is a saved instance with real values, and you can create as many as you like. A block class is the Python class that loads a document and adds behaviour, such as an S3 bucket block with upload and download methods.

A variable is a loose JSON value that any flow can read. It is handy for small settings. It has no field types, so nothing marks a value as sensitive.

Why blocks suit credentials

Three properties matter for secrets.

  1. Field level protection. A SecretStr field is stored with additional encryption and hidden by default in the UI. A variable has no such marker.
  2. Rotation without redeploying. The docs say block documents can be created and updated in the UI or API, and give credential rotation as an example, so you can change a secret without touching deployments.
  3. Reuse. One credentials block can serve many flows, so there is one place to rotate and one place to review who can read it.

What "additional encryption" does not promise

Read the claim carefully. It describes how the field is stored and displayed. It does not say that code running a flow cannot read the value, since a flow that loads the block needs it to connect. Anyone who can write or deploy flow code that loads a block can use its credentials. So the effective control is who can deploy flows and which workers they run on.

Ask these questions for each credentials block:

  • Which flows load it, and who can change those flows?
  • Does the credential have only the permissions the flows need?
  • Is there a rotation date, and who owns it?
  • Does the block hold a long lived key where a short lived token would do?

A simple rule set

DataWhere
Passwords, tokens, keysBlocks with SecretStr fields
Non-sensitive toggles, namesVariables
Large or file-based secretsYour secrets manager, referenced by a block or step

Do not put a secret in a variable because it is easier to read in code. Convenience is how credentials end up in screenshots and exports.

Reviewing what you already have

List your variables and look for values that resemble credentials. Move any you find into a block, update the flows, then rotate the old values. For a wider view of where credentials leak in pipelines, see ETL pipeline secrets: where credentials leak.

Safeguard's dependency scanning and policy gates look at the code and packages your flows depend on. You can try a free scan at gold.safeguard.sh/scan.

Quick check

Is a Secret in a block hidden from flow code?

No. A flow that loads the block can read the value, since it needs it to connect. The protection concerns storage and UI display.

Can I rotate a block credential without redeploying?

The Prefect docs say block documents can be updated in the UI or API, and mention rotating credentials without touching deployments as a use.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.