Skip to main content

Secrets

Alchemy provides built-in secret management to securely handle sensitive values like API keys, passwords, and credentials. Secrets are automatically encrypted when stored in state files, protecting your sensitive data.

What are Secrets?

Secrets in Alchemy are wrapper objects that:
  • Encrypt values when persisted to state files
  • Prevent accidental logging by overriding toString()
  • Maintain type safety through TypeScript
  • Integrate seamlessly with resource props
Without using secrets, sensitive values are stored in plain text in state files. Always wrap sensitive data with alchemy.secret().

Creating Secrets

From Environment Variables

The recommended approach uses alchemy.secret.env:
alchemy.secret.env.VAR_NAME automatically throws an error if the environment variable is not set, providing better error messages than manual checking.

From Literal Values

You can also create secrets from literal values:
Avoid hardcoding secrets in source code. Always use environment variables for production deployments.

Encryption Password

Secrets require a password for encryption. Set it globally:
Or via environment variables:
The password is used to encrypt/decrypt secrets in state files. Without it, operations involving secrets will fail.

Using Secrets in Resources

Secrets integrate seamlessly with resource properties:

How Secrets Work

Encryption in State Files

When resources are saved to state:
The actual value is encrypted using AES-256-GCM with your password.

Runtime Access

Secrets expose their values through the unencrypted property:
Secrets automatically prevent accidental exposure by overriding toString() and util.inspect.custom.

Secret Utilities

Wrapping Values

Ensure a value is a secret:

Unwrapping Values

Extract the raw value:

Type Guards

Check if a value is a secret:

Implementing Resources with Secrets

When creating custom resources that accept secrets:
Always unwrap secrets when making API calls, and wrap them in the resource output.

Scoped Passwords

Different scopes can use different encryption passwords:
Scoped passwords enable different teams or services to manage their own encryption keys.

Secret Recovery

If you lose your encryption password:

Option 1: Erase Secrets

This treats all secrets as undefined and allows you to redeploy with a new password.
--erase-secrets removes encrypted values permanently. You’ll need to provide new secret values after erasing.

Option 2: Manually Update State

Edit state files in .alchemy/ to remove or update encrypted values.

Option 3: Destroy and Recreate

Environment Variable Patterns

Named Secrets

Create secrets with custom names for better debugging:

Validation

Validate secrets before use:

Conditional Secrets

Use different secrets based on stage:

Type Safety

Secrets maintain full TypeScript type safety:

Security Best Practices

1

Never hardcode secrets

Always use environment variables or external secret managers
2

Rotate passwords regularly

Change encryption passwords periodically
3

Use strong passwords

Encryption password should be long and random (32+ characters)
4

Separate dev and prod passwords

Use different passwords for different stages
5

Don't commit .env files

Add .env to .gitignore
6

Use secret managers in CI/CD

Store passwords in GitHub Secrets, AWS Secrets Manager, etc.

Common Patterns

Database Credentials

OAuth Tokens

Multi-Provider Credentials

Debugging Secrets

Enable secret logging for debugging (use carefully):
Never enable secret debugging in production or commit debug logs.

Next Steps

Resources

Learn how to use secrets in resource properties

State Management

Understand how secrets are stored in state

Scopes

Manage scope-level password configuration

Environment Variables

Best practices for environment variable management