Robert Szomolanyi
11/04/2025, 4:26 PMMarvin
11/04/2025, 4:26 PMMarvin
11/04/2025, 4:31 PMSecretStr, SecretBytes, SecretDict in a block’s schema) are encrypted before being persisted to the block_documents table. When you read blocks via the API/UI, secret values are excluded by default unless you explicitly request them (e.g., API include_secrets=False by default).
- How it works: Prefect’s server uses Fernet (symmetric) encryption under the hood (encrypt_fernet / decrypt_fernet) to encrypt/decrypt block data on the server side.
- Cloud vs. self-hosted:
- Prefect Cloud: Data is encrypted in transit and at rest. Block data is encrypted with keys managed by Prefect; keys are backed by a cloud KMS and are unique per workspace. No action required on your side.
- Self-hosted server: Encryption is built-in and enabled by default via the same Fernet-based mechanism. There is no publicly documented environment variable or setting to supply your own encryption key or perform key rotation at this time.
Useful links
- Prefect security (Cloud encryption, per-workspace keys): Prefect Security
- Secret storage how-to: Store secrets with blocks
- Encryption utilities in the server: prefect.server.utilities.encryption
Notes and best practices
- The API omits secrets unless include_secrets=True is specified and the caller has permission.
- If you need customer-managed keys and rotation for self-hosted today, a common pattern is to store the real credentials in your external secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, etc.) and have your blocks reference those at runtime rather than persisting long-lived credentials directly in the block.
- Also ensure your database/storage layer is encrypted at rest (e.g., RDS/GCP/Azure encryption).
If you’re comfortable sharing: are you on Prefect Cloud or self-hosting? That will determine what options you have for key management and rotation.Robert Szomolanyi
11/04/2025, 4:37 PMMarvin
11/04/2025, 4:38 PMMarvin
11/04/2025, 4:38 PMSecretStr, SecretBytes, SecretDict) are encrypted at rest by the Prefect server using symmetric (Fernet) encryption. They’re also excluded from API/UI responses by default unless explicitly requested.
- How is this managed? The encryption/decryption is handled by the server via encrypt_fernet / decrypt_fernet. There is no publicly documented environment variable or setting to provide your own encryption key or to rotate it in OSS/self-hosted at this time.
- Key rotation / BYOK: Not currently exposed for self-hosted via documented settings. If you need customer-managed keys or a rotation schedule, the recommended pattern is to store real credentials in your external secrets manager (AWS Secrets Manager, GCP Secret Manager, Vault, etc.) and have your blocks reference those at runtime (store references or short-lived tokens in the block instead of long-lived creds).
- Additional hardening: Keep your database/storage encrypted at rest (e.g., RDS/GCP/Azure native encryption) and restrict access to API routes that can return decrypted values (the API omits secrets unless include_secrets=True and permissions allow it).
References
- Prefect security overview: Prefect Security
- How to store secrets with blocks: Store secrets with blocks
- Server encryption utilities (Fernet): prefect.server.utilities.encryption
If you have specific compliance requirements (e.g., customer-managed keys, rotation cadence, or proof of encryption implementation), let me know—happy to suggest an architecture or patterns that meet them.