Commands and usage
λ phase --help
Keep Secrets.
/$$
| $$
/$$$$$$ | $$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$
/$$__ $$| $$__ $$ |____ $$ /$$_____/ /$$__ $$
| $$ \ $$| $$ \ $$ /$$$$$$$| $$$$$$ | $$$$$$$$
| $$ | $$| $$ | $$ /$$__ $$ \____ $$| $$_____/
| $$$$$$$/| $$ | $$| $$$$$$$ /$$$$$$$/| $$$$$$$
| $$____/ |__/ |__/ \_______/|_______/ \_______/
| $$
|__/
Commands:
auth 💻 Authenticate with Phase
init 🔗 Link local project with Phase app
run 🚀 Run and inject secrets to your app
shell 🐚 Launch a sub-shell with secrets as environment variables
apps list 📋 List available apps and their environments
secrets list 📇 List all the secrets
secrets get 🔍 Fetch details about one or more secrets in JSON
secrets create 💳 Create a new secret
secrets update 📝 Update an existing secret
secrets delete 🗑️ Delete secrets
secrets import 📩 Import secrets from a .env file
secrets export 🥡 Export secrets in a specific format
dynamic-secrets list 📇 List dynamic secrets & metadata
dynamic-secrets lease generate ✨ Generate a lease (create fresh dynamic secret)
dynamic-secrets lease get 🔍 Get leases for a dynamic secret
dynamic-secrets lease renew 🔁 Renew a lease
dynamic-secrets lease revoke 🗑️ Revoke a lease
ai enable 🪄 Enable AI integrations and configure secret visibility
ai disable 🚫 Disable AI integrations
ai skill 📄 Print the Phase AI skill document
users whoami 🙋 See details of the current user
users switch 🪄 Switch between Phase users, orgs and hosts
users logout 🏃 Logout from phase-cli
users keyring 🔐 Display information about the Phase keyring
console 🖥️ Open the Phase Console in your browser
docs 📖 Open the Phase CLI Docs in your browser
completion ⌨️ Generate the autocompletion script for the specified shell
Flags:
-h, --help help for phase
-v, --version version for phase
Use "phase [command] --help" for more information about a command.
Available commands
To use Phase CLI, simply run:
> phase [command] [sub-command] [options]
To view all available commands and their descriptions, run:
> phase --help
> phase secrets -h
💻 auth
Authenticate with Phase using the CLI on your own machine. The phase auth command lets you log in to either Phase Cloud or a Self-hosted instance of Phase.
Phase CLI will automatically look for PHASE_HOST and or PHASE_SERVICE_TOKEN environment variables to authenticate with the Phase Service. If any are present, this will override any authentication medum previously chosen.
For more details, see Environment Variables.
Auth Methods:
- Webauth (Default): This automated method opens the Phase Console in your default browser for authentication. You'll simply enter your
sudopassword to authenticate the CLI seamlessly. For Self-Hosted instances, you'll be prompted to enter the host URL.
Note that during this process, an ephemeral X25519 keypair is generated and a crypto sealed box is used for enhanced security and no tokens or private keys are exchanged in plain text.
Example:
» phase auth
? Choose your Phase instance type: ☁️ Phase Cloud
Please authenticate via the Phase Console: https://console.phase.dev/webauth/OTM3MC00ZWViYmI1MGVlMTU3ZTliOWZk...
This opens the Phase Console in a new tab. Enter your sudo password when prompted. The CLI securely receives your credentials via encrypted POST requests to finalize authentication. If you are already authenticated, it will display your email address and provide instructions for switching accounts.
- Token: This allows you to authenticate to Phase directly uisng a Personal Access Token (PAT) or a Service Account Token that you may have manually created in the Phase Console.
For token mode, provide the following:
- Host URL - Only for Self-hosted instances
- Personal Access Token (PAT) or a Service Account Token
Obtain a Personal Access Token (PAT) from the Phase Console by going to Access Control -> Authentication -> Personal Access Tokens -> + Create Token.
- AWS IAM: Authenticate using your current AWS identity from the standard AWS credential chain (env vars, shared config/credentials, SSO, role assumption, instance profile, etc). Optionally bind the external identity to a Phase Service Account and set a TTL for the issued token. You'll need to have configured an external identity to a service account in the Phase Console first.
See External Identities for more details.
Usage:
> phase auth --mode aws-iam [--service-account-id SERVICE_ACCOUNT_ID] [--ttl SECONDS] [--no-store]
Options:
--service-account-id(Required): Service Account ID to map this external AWS identity to a Phase Service Account.--ttl(Optional): Token TTL in seconds for tokens created using external identities. Defaults to the configured Default TTL of the external identity.--no-store(Optional): Print the authentication token to STDOUT without storing credentials in the keyring.
Examples:
# Log in using your current AWS identity and persist credentials
> phase auth --mode aws-iam --service-account-id 0f1a2b3c-4d5e-6789-abcd-ef0123456789
phase auth --mode aws-iam --service-account=2115a1fc-0a78-4a7b-ad8c-6fa6cc15f489 --ttl 60 --no-store
{
"authentication": {
"tokenType": "ServiceAccount",
"token": "pss_service:v2:728a65904a8b66222e6488ee73d8b797391e8e54f0ed42af03a43b96a623b7a2:a7579d80027dddebb934f532ef6977a50d82dfbaa87f1b021cfef72086884605:d2f05a4bf13cea53a41d06fa2aad265ec9068aefa4609446b4c29743e6436e07:b17346b16aef0a2c25e05814a5a0f54555100965f1d6fb41e023989eab99c791",
"bearerToken": "ServiceAccount 728a65904a8b66222e6488ee73d8b797391e8e54f0ed42af03a43b96a623b7a2",
"TTL": 60,
"maxTTL": 86400
}
}
The CLI will auto detect the AWS region you are in and use it to authenticate with the AWS API. You can also use aws configure to set the region.
- Azure: Authenticate using your current Azure identity via
DefaultAzureCredential(Managed Identity, Service Principal, Workload Identity, Azure CLI, etc). You'll need to have configured an Azure external identity on a service account in the Phase Console first.
See External Identities for more details.
Usage:
> phase auth --mode azure [--service-account-id SERVICE_ACCOUNT_ID] [--azure-resource RESOURCE] [--ttl SECONDS] [--no-store]
Options:
--service-account-id(Required): Service Account ID to map this external Azure identity to a Phase Service Account.--azure-resource(Optional): Azure AD resource/audience for the token request. Must match the "Resource / Audience" configured on the Phase identity. Default:https://management.azure.com/.--ttl(Optional): Token TTL in seconds. Defaults to the configured Default TTL of the external identity.--no-store(Optional): Print the authentication token to STDOUT without storing credentials in the keyring.
Examples:
# Log in using your current Azure identity and persist credentials
> phase auth --mode azure --service-account-id 0f1a2b3c-4d5e-6789-abcd-ef0123456789
# Authenticate with a custom resource and print token to STDOUT
> phase auth --mode azure --service-account-id 0f1a2b3c-4d5e-6789-abcd-ef0123456789 --azure-resource "https://management.azure.com/" --ttl 3600 --no-store
DefaultAzureCredential automatically tries (in order): environment variables (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET), Workload Identity (Kubernetes), Managed Identity (IMDS), Azure CLI (az login), and Azure Developer CLI (azd login).
Auth Options Summary
mode: Choose the mode of authentication (token,webauth,aws-iam,azure). Default:webauthservice-account-id(Required for external identities): Bind external identity to a Phase Service Account.ttl(Optional): Only applicable when using external identities for authentication. TTL in seconds for the issued token.no-store(Optional): Only applicable when using external identities for authentication. Print the authentication token response to STDOUT without storing credentials.azure-resource(Optional, Azure only): Azure AD resource/audience. Default:https://management.azure.com/.
🔗 init
Link your local application or project to your Phase app. The phase init command creates a .phase.json file in the root of your projects which holds important contexts for the phase cli, so you don't have to pass arguments repetitively. This file does not contain any sensitive information and can be check into your git repo.
Usage:
# Interactive (prompts for app, environment, monorepo)
> phase init
# Non-interactive (for CI/CD or AI agents)
> phase init --app-id APP_ID --env ENVIRONMENT [--monorepo]
--app-id: (Optional) Application ID. When provided with--env, skips interactive prompts.--env: (Optional) Environment name. When provided with--app-id, skips interactive prompts.--monorepo: (Optional) Enable monorepo support. Default isfalse.
During interactive mode, you'll be asked to:
- Select an App previously created in the Phase Console
- Choose a default Environment
- Enable monorepo support (optional)
> phase init
? Select an App: [use arrow keys]
ferrari
» keyspace
inception
Exit
? Choose a Default Environment: Development
? 🍱 Monorepo support: Would you like this configuration to apply to subdirectories? (y/N)
Choosing an app will create a .phase.json configuration file in your project's working directory:
> phase init
? Select an App: keyspace
? Choose a Default Environment: Development
? 🍱 Monorepo support: Would you like this configuration to apply to subdirectories? y
✅ Initialization completed successfully.
> cat .phase.json
{
"version": "2",
"phaseApp": "keyspace",
"appId": "511f26b7-5b56-47f3-920e-a4edb9cdbf3c",
"defaultEnv": "Development",
"envId": "679bf2bc-9353-4fe0-a84f-825f284c8f8d",
"monorepoSupport": true
}
Tips:
- Modify the
defaultEnvin.phase.jsonto set the default environment context for the Phase CLI. For example,"defaultEnv": "production". - When monorepo support is enabled, the CLI will search parent directories for a
.phase.jsonconfig up to a maximum depth of 8 directories (configurable viaPHASE_CONFIG_PARENT_DIR_SEARCH_DEPTH). This allows you to have a single config at the root of your monorepo that applies to all sub-projects.
Example directory structure:
monorepo/
├── .phase.json (with monorepoSupport: true)
├── service-a/
│ └── src/
├── service-b/
│ └── src/
└── apps/
└── web/
└── src/
In this example, running Phase CLI commands from any subdirectory will use the root .phase.json config.
🚀 run
Run and inject secrets into your app with the ability to override default settings.
Usage:
> phase run [--env ENVIRONMENT] [--app APP_NAME] [--tags TAGS] [command_to_run]
command_to_run: The command you wish to run, such asyarn dev. You can also chain multiple command together by wrapping them in double quotes, example:phase run "printenv | grep secret"--env: (Optional) Specify the environment (e.g.,dev,staging,production). Supports partial string matching eg.prodforproductionDefault isdevelopment--path: (Optional) Specific path under which to fetch secrets from and inject into your application. Default is '/'. Pass an empty string""to fetch secrets from all paths.--app: (Optional) Name of your Phase application. Use this if you don't have a.phase.jsonfile in your project directory or want to override it.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--tags: (Optional) Comma-separated list of tags to filter secrets.--generate-leases: (Optional) Whether to generate leases for dynamic secrets (true/false). Default:true.--lease-ttl: (Optional) TTL in seconds to use when generating leases.
The run command executes your specified shell command, setting environment variables to the secrets fetched from Phase. It resolves cross-environment and local references in secrets.
Examples:
> phase run yarn dev
> phase run --env dev "printenv | grep DJANGO_SECRET_KEY"
DJANGO_SECRET_KEY=7842cc89c5a703acdf4797e0f063e1851734cea0677ad9382158cfcee26195df
Injecting Referenced secrets:
> phase secrets get PROD_AWS_KEY --env dev
{
"key": "PROD_AWS_KEY",
"value": "${prod.AWS_ACCESS_KEY_ID}",
"comment": "",
"path": "/",
"application": "example-app",
"environment": "Development",
"tags": [],
"overridden": false
}
> phase run --env dev "printenv | grep PROD_AWS_KEY"
PROD_AWS_KEY=AKIA2OGYBAH63UA3VNFG
Note that secrets get returns the raw, unresolved reference syntax (${prod.AWS_ACCESS_KEY_ID}), while phase run automatically resolves references and injects the actual secret value.
Chaining multiple commands:
> phase run --env prod "python manage.py migrate && python manage.py runserver backend:8000"
Additional Notes:
- The
phase runonly exposes secrets to your applications runtime and not to the rest of your system for security reasons. - When specifying tags with
--tags, only secrets matching these tags will be injected into the environment. - Cross-environment and local references in secrets are automatically resolved and injected. Warnings are issued if any references cannot be resolved.
- Errors during the command execution or secret fetching process will result in an appropriate error message and termination of the process.
- When dynamic secrets are configured, the CLI will automatically generate leases and inject the freshly created dynamic secrets along with static secrets. Control this behavior with
--generate-leasesand--lease-ttl. - AI mode: Commands that dump environment variables (
printenv,env,export,set,declare,compgen) are blocked when the CLI detects an AI agent, to prevent secret exposure.
🐚 shell
Launch an ephemeral shell with secrets injected as environment variables.
Usage:
> phase shell [--env ENVIRONMENT] [--app APP_NAME] [--shell SHELL_TYPE] [--path PATH] [--tags TAGS]
--env: (Optional) Specify the environment (e.g.,dev,staging,production). Default isdevelopment--path: (Optional) Specific path under which to fetch secrets from and inject into your shell. Default is '/'. Pass an empty string""to fetch secrets from all paths.--app: (Optional) Name of your Phase application. Use this if you don't have a.phase.jsonfile in your project directory or want to override it.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--shell: (Optional) Specify the shell to launch. Supported shells:bash,zsh,fish,sh,powershell,pwsh,cmd. Default is your current shell.--tags: (Optional) Comma-separated list of tags to filter secrets.--generate-leases: (Optional) Whether to generate leases for dynamic secrets (true/false). Default:true.--lease-ttl: (Optional) TTL in seconds to use when generating leases.
The shell command launches a new shell session with your Phase secrets loaded as environment variables. This is useful for local development workflows where you need to work with multiple commands, scripts, and tools, and running phase run for each command may not be practical.
Examples:
# Launch a zsh shell with secrets from the development environment
> phase shell
[15:32:00] 🐚 Initialized zsh with 15 secrets from Application: example-app, Environment: Development
Remember: Secrets are only available in this session. Type exit or press Ctrl+D to exit.
> echo $POSTGRES_CONNECTION_STRING
postgresql://postgres:dbc76c4d...@localhost:5432/mydb
# Exit the shell using Ctrl+D or by typing 'exit'
> exit
[15:33:29] 🐚 Shell session ended. Phase secrets are no longer available.
Notes:
- When using zsh with modifications like powerline10k, command suggestions and tab completions might be affected in certain cases. This is not due to the Phase CLI - you can verify this by launching zsh directly.
- Secrets are only available within the shell session and are automatically cleared when you exit.
- Inside the shell,
PHASE_ENVis set to the full environment name from the fetched secrets (e.g., "Development", "Production"). - Inside the shell,
PHASE_APPis set to the full application name from the fetched secrets. (e.g., "example-app") - When dynamic secrets are configured, the CLI can automatically generate leases and provision the freshly created dynamic secrets along with static secrets. Control this behavior with
--generate-leasesand--lease-ttl. - AI mode:
phase shellis blocked entirely when invoked by an AI agent. Usephase run <command>instead.
📱 apps
📋 apps list
List all available applications and their environments as JSON. Useful for scripting, CI/CD, and AI agents that need to discover app IDs for non-interactive phase init.
Usage:
> phase apps list
Example:
> phase apps list
[
{
"id": "511f26b7-5b56-47f3-920e-a4edb9cdbf3c",
"name": "my-app",
"environments": [
{ "id": "679bf2bc-9353-4fe0-a84f-825f284c8f8d", "name": "Development", "env_type": "DEV" },
{ "id": "a1b2c3d4-e5f6-7890-abcd-ef0123456789", "name": "Production", "env_type": "PROD" }
]
}
]
🗝️ secrets
Manage your secrets with various sub-commands.
📇 secrets list
List all the secrets in a specified environment, with options to show uncensored secrets, filter by app, and filter by tags.
Usage:
> phase secrets list [--show] [--env ENVIRONMENT] [--app APP_NAME] [--tags TAGS]
--show: Display secrets uncensored. If you have dynamic secrets configured, the CLI will automatically generate leases and display the values of the freshly created dynamic secrets along with static secrets in the table.--env: (Optional) Specify the environment. Default isdevelopment--path: (Optional) The path in which you want to list secrets. Default is '/'. Pass an empty string""to list secrets from all paths.--app: (Optional) Name of your Phase application. Use this to override the.phase.jsonfile or when it's not present in your project directory.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--tags: (Optional) Comma-separated list of tags to filter secrets.--generate-leases: (Optional) Whether to generate leases for dynamic secrets. Defaults to the value of--show.--lease-ttl: (Optional) TTL in seconds to use when generating leases.
Indicators:
🔒: Sealed secret (write-only — value cannot be read back after creation).🔧: Config secret (non-sensitive configuration value, stored unencrypted).🔗: Secret references another secret in the same environment.🌐: Cross-environment reference (secret from another environment in the same or different application).🔖: Tag associated with the secret.💬: Comment associated with the secret.🔏: Personal secret override (visible only to you).⚡️: Dynamic secret.
AI mode behaviour: config-type secrets are always shown in plaintext (even without --show). When invoked by an AI agent, sealed secrets show as [REDACTED] and secret-type values are redacted based on ai.json configuration.
🔍 secrets get
Fetch details about one or more secrets in JSON, with the ability to specify the application and filter by tags.
Usage:
> phase secrets get KEY [KEY...] [--env ENVIRONMENT] [--app APP_NAME] [--tags TAGS]
KEY: One or more keys to fetch. Single key returns a JSON object; multiple keys returns a JSON array.--env: (Optional) Specify the environment in which to search for the secret.--path: (Optional) The path from which to fetch the secret from. Default is '/'--app: (Optional) Name of your Phase application. Use this option to override the.phase.jsonfile in your project directory or when it's not present.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--tags: (Optional) Comma-separated list of tags to filter secrets.--generate-leases: (Optional) Whether to generate leases for dynamic secrets (true/false). Default:true.--lease-ttl: (Optional) TTL in seconds to use when generating leases.
Example:
> phase secrets get DJANGO_DEBUG
{
"key": "DEBUG",
"value": "True",
"comment": "This is only for local development. NOT to be used in production.",
"path": "/",
"application": "example-app",
"environment": "Development",
"tags": [
"local-development"
],
"overridden": false
}
Dynamic secret example:
> phase secrets get AWS_IAM_USERNAME
{
"key": "AWS_IAM_USERNAME",
"value": "wwm6hwzpbpnvxs",
"comment": "",
"path": "/",
"application": "example-app",
"environment": "Development",
"tags": [],
"overridden": false,
"is_dynamic": true,
"dynamic_group": "AWS IAM credentials (aws)"
}
Multiple keys example:
> phase secrets get DATABASE_HOST DATABASE_PORT
[
{
"key": "DATABASE_HOST",
"value": "localhost",
...
},
{
"key": "DATABASE_PORT",
"value": "5432",
...
}
]
Notes:
- Single key returns a JSON object (backwards compatible). Multiple keys returns a JSON array.
- The
getcommand provides a JSON-formatted output including key details such as the secret value, whether it's overridden, tags associated with it, and any comments. - Using the
--tagsoption allows you to filter the secret based on specific tags. - If you have dynamic secrets configured and try to fetch one by key, the CLI will automatically generate a lease and return the value of the freshly created dynamic secret.
- When invoked by an AI agent, sealed and secret-type values are redacted based on
ai.jsonconfiguration.
💳 secrets create
Create a new secret with options to input the value manually, read from stdin, or generate a random value of specified type and length.
Usage:
> phase secrets create [KEY] [--env ENVIRONMENT] [--app APP_NAME] [--random TYPE] [--length LENGTH] [--override] [--type TYPE]
KEY: (Optional) The key for the new secret. It will be converted to uppercase. If the value is not provided as an argument, it will be read from stdin.--env: (Optional) Specify the environment where the secret will be created.--path: (Optional) The path in which you want to create a secret. You can create a directory by simply specifying a path like so:--path /folder/SECRET. Default is '/'--app: (Optional) Name of your Phase application. Use this to override the.phase.jsonfile or when it's not present in your project directory.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--random: (Optional) Specify the type of random value to generate. Available types arehex,alphanumeric,base64,base64url,key128,key256. Example:--random hex.--length: (Optional) Specify the length of the random value. Applicable for types other thankey128andkey256. Default length is 32. Example:--length 16.--override: (Optional) Update the personal override value.--type: (Optional) Secret type. One ofsecret(default),sealed(write-only — value cannot be read back after creation), orconfig(non-sensitive configuration value).
Examples:
# Create a secret by reading the value from stdin
> cat ~/.ssh/id_rsa | phase secrets create SSH_PRIVATE_KEY
# Create a secret with a randomly generated hexadecimal value of 32 characters
> phase secrets create RAND --random hex --length 32
# Create a sealed secret (value cannot be read back)
> phase secrets create STRIPE_KEY --type sealed
# Create a config value (non-sensitive, stored unencrypted)
> phase secrets create APP_PORT --type config
Notes:
base64: Random bytes, base64 encodedbase64url: Random bytes, base64url encoded (URL-safe)key128: 16 Byte high entropy base64 encoded symmetric key - suitable for AES-128key256: 32 Byte high entropy base64 encoded symmetric key - suitable for use with ChaCha20 or AES-256
📝 secrets update
Update an existing secret with options to input the new value manually, read from stdin, or generate a random value of specified type and length.
Usage:
> phase secrets update KEY [--env ENVIRONMENT] [--app APP_NAME] [--random TYPE] [--length LENGTH] [--override] [--toggle-override] [--type TYPE]
KEY: The key associated with the secret to update. If the new value is not provided as an argument, it will be read from stdin.--env: (Optional) Specify the environment where the secret will be updated.--path: (Optional) The current path of the secret to update. Default is '/'--updated-path: (Optional) The new path for the secret, if changing its location. If not provided, the secret's path is not updated. Example usage: --updated-path "/folder/subfolder"--app: (Optional) Name of your Phase application. Use this to override the.phase.jsonfile or when it's not present in your project directory.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--random: (Optional) Specify the type of random value to generate. Available types arehex,alphanumeric,base64,base64url,key128,key256. Example:--random hex.--length: (Optional) Specify the length of the random value. Applicable for types other thankey128andkey256. Default length is 32. Example:--length 16.--override: (Optional) Update the personal override value.--toggle-override: (Optional) Toggle the override state between active and inactive.--type: (Optional) Change the secret type. One ofsecret,sealed, orconfig.
Examples:
# Update a secret by manually entering a new value
> phase secrets update DEBUG
# Update a secret by piping a value via stdin
> cat ~/.ssh/id_ed25519 | phase secrets update SSH_PRIVATE_KEY
# Update a secret with a randomly generated hexadecimal value of 32 characters
> phase secrets update MY_SECRET_KEY --random hex --length 32
# Update a secret with a personal override value
> phase secrets update POSTGRES_CONNECTION_STRING --override
# Toggle the override state of a secret
> phase secrets update POSTGRES_CONNECTION_STRING --toggle-override
# Change only the secret type (no value prompt)
> phase secrets update APP_PORT --type config
> phase secrets update API_KEY --type sealed
Notes:
base64: Random bytes, base64 encodedbase64url: Random bytes, base64url encoded (URL-safe)key128: 16 Byte high entropy base64 encoded symmetric key - suitable for AES-128key256: 32 Byte high entropy base64 encoded symmetric key - suitable for use with ChaCha20 or AES-256
🗑️ secrets delete
Delete one or more secrets from a specified environment, with an option to specify the application.
Usage:
> phase secrets delete KEYS... [--env ENVIRONMENT] [--app APP_NAME]
KEYS...: One or more keys of the secrets to be deleted. Separate multiple keys with spaces.--env: (Optional) Specify the environment from which the secrets will be deleted.--path: (Optional) Path filter for deleting secrets. Default is/. Pass an empty string""to delete from all paths.--app: (Optional) Name of your Phase application. Use this to override the.phase.jsonfile or when it's not present in your project directory.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.
Example:
# Delete a single secret
> phase secrets delete DEBUG
Successfully deleted the secret.
# Delete multiple secrets
> phase secrets delete SECRET1 SECRET2 SECRET3
Successfully deleted the secrets.
Notes:
- The
deletecommand can be used to remove a single secret or multiple secrets at once by providing their keys as arguments. - If you have an
.phase.jsonfile in your project directory, it will be used to determine the default application. Use the--appoption to override this behavior.
📩 secrets import
Import secrets into your Phase environment from a .env file, with an option to specify the application.
Usage:
> phase secrets import ENV_FILE [--env ENVIRONMENT] [--app APP_NAME] [--type TYPE]
ENV_FILE: The path to the.envfile from which the secrets will be imported.--env: (Optional) Specify the environment where the secrets will be imported.--path: (Optional) The path to which you want to import secret(s). Default is '/'--app: (Optional) Name of your Phase application. Use this to override the.phase.jsonfile or when it's not present in your project directory.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--type: (Optional) Secret type to apply to all imported secrets. One ofsecret(default),sealed, orconfig.
Example:
# View the contents of the .env file
> cat .env
AWS_ACCESS_KEY_ID="AKIA2OGYBAH63UA3VNFG"
AWS_SECRET_ACCESS_KEY="V5yWXDe82Gohf9DYBhpatYZ74a5fiKfJVx8rx6W1"
# Import secrets from the .env file into the 'prod' environment
> phase secrets import .env --env prod
Successfully imported and encrypted 2 secrets.
To view them please run: phase secrets list --env prod
# List imported secrets in the 'prod' environment
> phase secrets list --env prod
# Optional: Remove the .env file if no longer needed
> rm .env
Notes:
- The
importcommand reads key-value pairs from the specified.envfile and imports them as secrets into the chosen environment. - If an
.phase.jsonfile exists in your project directory, it will determine the default application. The--appoption can be used to override this behavior.
🥡 secrets export
Export secrets from your Phase environment, with options to filter by keys, tags, and to specify the export format.
Usage:
> phase secrets export [keys...] [--env ENVIRONMENT] [--app APP_NAME] [--tags TAGS] [--format FORMAT]
keys...: (Optional) One or more specific secret keys to export. If omitted, all secrets are exported.--env: (Optional) Specify the environment from which the secrets will be exported.--path: (Optional) The path from which you want to export secret(s). Default is '/'. Pass an empty string""to export secrets from all paths.--app: (Optional) Name of your Phase application. Use this to override the.phase.jsonfile or when it's not present in your project directory.--app-id: (Optional) ID of your Phase application. Takes precedence over--appif both are provided.--tags: (Optional) Comma-separated list of tags to filter the secrets. Supports partial matching and treats underscores as spaces.--format: (Optional) Specify the export format. Supported formats aredotenv,kv,json,csv,yaml,xml,toml,hcl,ini,java_properties. Default format isdotenv.--generate-leases: (Optional) Whether to generate leases for dynamic secrets (true/false). Default:true.--lease-ttl: (Optional) TTL in seconds to use when generating leases.
Examples:
# Export all the secrets in the 'prod' environment to dotenv format
> phase secrets export --env prod
AWS_ACCESS_KEY_ID="AKIA2OGYBAH63UA3VNFG"
AWS_SECRET_ACCESS_KEY="V5yWXDe82Gohf9DYBhpatYZ74a5fiKfJVx8rx6W1"
# Export all secrets in the 'dev' environment to a .env file
> phase secrets export --env dev > .env.example
# Export only specific keys
> phase secrets export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY --env prod
AWS_ACCESS_KEY_ID="AKIA2OGYBAH63UA3VNFG"
AWS_SECRET_ACCESS_KEY="V5yWXDe82Gohf9DYBhpatYZ74a5fiKfJVx8rx6W1"
# Export secrets with specific tags in 'dev' environment to JSON format
> phase secrets export --env dev --tags "tag1,tag2" --format json
{
"AWS_SECRET_ACCESS_KEY": "V5yWXDe82Gohf9DYBhpatYZ74a5fiKfJVx8rx6W1",
"DB_NAME": "XP1_LM",
}
Notes:
- The
exportcommand allows you to export secrets in various formats:dotenv(.env): Key-value pairs in a simple text format with values wrapped in double quoteskv: Simple key-value pairs with uppercase keys and raw valuesjson: JavaScript Object Notation, useful for integration with various tools and languagescsv: Comma-Separated Values, a simple text format for tabular datayaml: Human-readable data serialization format, often used for configuration filesxml: Extensible Markup Language, suitable for complex data structurestoml: Tom's Obvious, Minimal Language, a readable configuration file formathcl: HashiCorp Configuration Language, used in HashiCorp tools like Terraformini: A simple format often used for configuration filesjava_properties: Key-value pair format commonly used in Java applications
- Use the
--tagsoption to filter secrets by tags, which supports partial matching and considers underscores as spaces. - If an
.phase.jsonfile exists in your project directory, it will determine the default application. The--appoption can be used to override this behavior. - If you have dynamic secrets configured, the CLI will automatically generate leases and export the values of the freshly created dynamic secrets along with static secrets.
- AI mode: When invoked by an AI agent, sealed and secret-type values are replaced with
[REDACTED]in the exported output.
⚡️ dynamic-secrets
Manage dynamic secrets and their short-lived credentials (leases).
📇 dynamic-secrets list
List dynamic secret definitions (metadata) available to your app and environment.
Usage:
> phase dynamic-secrets list [--env ENVIRONMENT] [--app APP_NAME] [--app-id APP_ID] [--path PATH]
--env: (Optional) Specify the environment. Default isdevelopment.--app: (Optional) Name of your Phase application.--app-id: (Optional) ID of your Phase application. Takes precedence over--app.--path: (Optional) Path to filter dynamic secrets. Default is/.
Examples:
> phase dynamic-secrets list
[
{
"id": "3d07788d-a32a-4d54-8d7d-cc11efdfe424",
"name": "AWS IAM credentials - docs example",
"type": "dynamic",
"description": "",
"environment": "febb85cd-561b-4d96-b20a-2cfd799586c1",
"folder": null,
"path": "/",
"defaultTtl": "01:00:00",
"maxTtl": "1 00:00:00",
"provider": "aws",
"keyMap": [
{
"id": "username",
"masked": false,
"keyName": "AWS_IAM_USERNAME",
"keyDigest": "bff90b6333a7af45e6c78f1c880fa626b3f93545ab5f21489df825bb38fed672"
},
{
"id": "access_key_id",
"masked": false,
"keyName": "AWS_ACCESS_KEY_ID",
"keyDigest": "a2c461ab14cc191f084bd7dda3b566dee65c6a287cf33b29b07f42bf35107c19"
},
{
"id": "secret_access_key",
"masked": true,
"keyName": "AWS_SECRET_ACCESS_KEY",
"keyDigest": "3813f891ac1901d258b20b7aa2b3108949971bcbdce380bf537c9da195b7c166"
}
],
"createdAt": "2025-09-26T09:48:34.012281Z",
"updatedAt": "2025-09-26T09:48:34.012301Z",
"deletedAt": null,
"lease": null
},
]
📜 dynamic-secrets lease
Manage leases (ephemeral credentials) for dynamic secrets.
🔍 dynamic-secrets lease get
Get active leases for a dynamic secret.
Usage:
> phase dynamic-secrets lease get SECRET_ID [--env ENVIRONMENT] [--app APP_NAME] [--app-id APP_ID] [--path PATH]
SECRET_ID: The dynamic secret ID.--env,--app,--app-id: Context flags as above.--path: Present for parity; not required for lease operations.
Example:
> phase dynamic-secrets lease get 3d07788d-a32a-4d54-8d7d-cc11efdfe424
[
{
"id": "dc3e86c5-acb8-42ca-8dfc-cb2c28fc0498",
"name": "AWS IAM credentials",
"description": "",
"secret": "3d07788d-a32a-4d54-8d7d-cc11efdfe424",
"ttl": "01:00:00",
"status": "expired",
"owner": {
"type": "organisation_member",
"data": {
"id": "f1a8ede5-c96b-4514-b4f2-2b88bcce0b2e",
"username": "nimish-ks",
"fullName": "Nimish",
"email": "[email protected]",
"role": {
"id": "4bc0d6b1-8d3d-4dad-a2b2-cece14bd9ee4",
"name": "Owner"
}
}
},
"credentials": [],
"createdAt": "2025-09-29T12:31:01.405885Z",
"renewedAt": null,
"expiresAt": "2025-09-29T13:31:01.405477Z",
"revokedAt": "2025-09-29T13:31:28.963104Z",
"deletedAt": null
},
{
"id": "09624959-5907-40b8-8ae8-a0ab352b59fc",
"name": "AWS IAM credentials",
"description": "",
"secret": "3d07788d-a32a-4d54-8d7d-cc11efdfe424",
"ttl": "01:00:00",
"status": "expired",
"owner": {
"type": "organisation_member",
"data": {
"id": "f1a8ede5-c96b-4514-b4f2-2b88bcce0b2e",
"username": "nimish-ks",
"fullName": "Nimish",
"email": "[email protected]",
"role": {
"id": "4bc0d6b1-8d3d-4dad-a2b2-cece14bd9ee4",
"name": "Owner"
}
}
},
"credentials": [],
"createdAt": "2025-09-29T11:27:56.206673Z",
"renewedAt": null,
"expiresAt": "2025-09-29T12:27:56.206276Z",
"revokedAt": "2025-09-29T12:28:28.911349Z",
"deletedAt": null
}
]
🔁 dynamic-secrets lease renew
Renew an existing lease by a specified TTL (in seconds).
Usage:
> phase dynamic-secrets lease renew LEASE_ID TTL [--env ENVIRONMENT] [--app APP_NAME] [--app-id APP_ID]
LEASE_ID: Lease identifier to renew.TTL: Renewal duration in seconds.
Example:
> phase dynamic-secrets lease renew ce6ebf1a-c008-4379-9ed6-351dd763f18b 3600
{
"message": "Lease renewed successfully. Updated expiry: 2025-09-29 14:45:50.912286+00:00"
}
🗑️ dynamic-secrets lease revoke
Revoke an existing lease, immediately invalidating the credentials.
Usage:
> phase dynamic-secrets lease revoke LEASE_ID [--env ENVIRONMENT] [--app APP_NAME] [--app-id APP_ID]
Example:
> phase dynamic-secrets lease revoke ce6ebf1a-c008-4379-9ed6-351dd763f18b
{
"message": "Lease revoked successfully"
}
✨ dynamic-secrets lease generate
Generate a new lease (create fresh ephemeral credentials) for a dynamic secret.
Usage:
> phase dynamic-secrets lease generate SECRET_ID [--lease-ttl SECONDS] [--env ENVIRONMENT] [--app APP_NAME] [--app-id APP_ID]
SECRET_ID: The dynamic secret ID.--lease-ttl: (Optional) TTL in seconds for the generated lease. If omitted, the default TTL is used.
Example:
> phase dynamic-secrets lease generate 3d07788d-a32a-4d54-8d7d-cc11efdfe424
[
{
"id": "3d07788d-a32a-4d54-8d7d-cc11efdfe424",
"name": "AWS IAM credentials - docs example",
"type": "dynamic",
"description": "",
"environment": "febb85cd-561b-4d96-b20a-2cfd799586c1",
"folder": null,
"path": "/",
"defaultTtl": "01:00:00",
"maxTtl": "1 00:00:00",
"provider": "aws",
"keyMap": [
{
"id": "username",
"masked": false,
"keyName": "AWS_IAM_USERNAME",
"keyDigest": "bff90b6333a7af45e6c78f1c880fa626b3f93545ab5f21489df825bb38fed672"
},
{
"id": "access_key_id",
"masked": false,
"keyName": "AWS_ACCESS_KEY_ID",
"keyDigest": "a2c461ab14cc191f084bd7dda3b566dee65c6a287cf33b29b07f42bf35107c19"
},
{
"id": "secret_access_key",
"masked": true,
"keyName": "AWS_SECRET_ACCESS_KEY",
"keyDigest": "3813f891ac1901d258b20b7aa2b3108949971bcbdce380bf537c9da195b7c166"
}
],
"createdAt": "2025-09-26T09:48:34.012281Z",
"updatedAt": "2025-09-26T09:48:34.012301Z",
"deletedAt": null,
"lease": {
"id": "d43fa19b-9060-4acf-b6d9-36c1e832c1bb",
"name": "AWS IAM credentials",
"description": "",
"secret": "3d07788d-a32a-4d54-8d7d-cc11efdfe424",
"ttl": "01:00:00",
"status": "active",
"owner": {
"type": "organisation_member",
"data": {
"id": "f1a8ede5-c96b-4514-b4f2-2b88bcce0b2e",
"username": "nimish-ks",
"fullName": "Nimish",
"email": "[email protected]",
"role": {
"id": "4bc0d6b1-8d3d-4dad-a2b2-cece14bd9ee4",
"name": "Owner"
}
}
},
"credentials": [
{
"key": "AWS_IAM_USERNAME",
"value": "ybm0vi9yk"
},
{
"key": "AWS_ACCESS_KEY_ID",
"value": "AKIAVWFM2HYO*********"
},
{
"key": "AWS_SECRET_ACCESS_KEY",
"value": "ozznB6pSagoTalgG************"
}
],
"createdAt": "2025-09-29T13:47:24.199689Z",
"renewedAt": null,
"expiresAt": "2025-09-29T14:47:24.199283Z",
"revokedAt": null,
"deletedAt": null
}
}
]
Notes:
- Leases are time-bound credentials. When they expire (or are revoked), the credentials stop working.
- Commands like
phase run,phase shell,phase secrets get, andphase secrets exportcan automatically generate leases when injecting or exporting dynamic secrets. Control this with--generate-leasesand--lease-ttl. This will allow you to make use of dynamic secrets without having to make any changes to your application code.
🥷 ai
Configure AI integrations for Phase. The ai command group controls how AI coding agents interact with your Phase secrets. When enabled, the CLI installs a skill document to your AI tool's global skill directory and applies security guardrails automatically.
See AI agent integration pages for setup guides for each supported tool.
🪄 ai enable
Enable AI integrations: installs the Phase skill document for your chosen AI agent and configures secret visibility. This command cannot be run by AI agents — it must be run by the user directly.
Usage:
# Interactive — select AI agent and visibility
> phase ai enable
# Non-interactive
> phase ai enable --mask --path ~/.claude/skills/phase-cli/SKILL.md
> phase ai enable --no-mask --path ~/.cursor/skills/phase-cli/SKILL.md
Interactive mode first asks which AI agent to install for, then prompts for secret visibility:
🪄 Install Phase AI skill for
❯ Claude Code (global) → ~/.claude/skills/phase-cli/SKILL.md
Cursor (global) → ~/.cursor/skills/phase-cli/SKILL.md
VS Code Copilot (global) → ~/.copilot/skills/phase-cli/SKILL.md
Codex (global) → ~/.agents/skills/phase-cli/SKILL.md
OpenCode (global) → ~/.config/opencode/skills/phase-cli/SKILL.md
Custom path...
🔒 Mask secret values from AI agents?
❯ Yes — mask secret values (recommended for production)
No — allow AI to read secret values (e.g. development environments)
Sealed secret values are always hidden from AI tools regardless of this setting. This is a hard security boundary — sealed secrets (API keys, tokens, passwords) can only be created/updated with random generation and their values never appear in AI conversations.
Value visibility by type and setting:
| Secret Type | maskSecretValues: true (default) | maskSecretValues: false |
|---|---|---|
sealed | Hidden | Hidden |
secret | Hidden | Visible |
config | Visible | Visible |
🚫 ai disable
Disable AI integrations. Removes ~/.phase/ai.json and uninstalls the skill document from all known AI agent directories.
> phase ai disable
📄 ai skill
Print the raw Phase AI skill document to stdout. Useful for piping to a custom location or inspecting the skill content.
> phase ai skill
> phase ai skill > /path/to/custom/SKILL.md
AI Security Guardrails
When the CLI detects it is being run by an AI agent:
- Output redaction:
secrets list,secrets get, andsecrets exportautomatically redact values based on secret type andai.jsonsettings. Redacted values show as[REDACTED]. - Blocked commands:
phase runrefuses to execute commands that dump environment variables (printenv,env,export,set,declare,compgen), since these would expose injected secrets. - Shell blocked:
phase shellis entirely blocked in AI mode to prevent unrestricted access to injected secrets. - AI commands blocked:
phase ai enableandphase ai disablecannot be run by AI agents.
AI agent detection works via environment variables set by supported tools:
- Claude Code:
CLAUDECODE=1 - Cursor:
CURSOR_AGENT=1 - OpenAI Codex:
CODEX=1 - OpenCode:
OPENCODE=1 - Cross-tool convention:
AGENT=<name>(Codex, Goose, Amp, etc.)
👥 users
Manage users and accounts in the Phase CLI. This command includes sub-commands for user management.
🙋 users whoami
See details of the current user.
Usage:
> phase users whoami
This command displays information about the currently logged-in user in the Phase CLI.
Example:
> phase users whoami
✉️ Email: [email protected]
🙋 User ID: c9324ace-4605-4017-9425-0632524f4750
🏢 Organization: spacex
☁️ Host: https://console.phase.dev
🪄 users switch
Switch contexts between Phase users, orgs and hosts.
Usage:
> phase users switch
This command displays a list of user accounts that the Phase CLI is authenticated to, across orgs and instances. Simply use the up/down arrow keys (↑ and ↓) and hit enter to switch the account context.
Example:
> phase users switch
? Choose a user to switch to: (Use arrow keys)
🏢 Organization, ✉️ Email, ☁️ Phase Host, 🆔 User ID
» spacex, [email protected], https://console.phase.dev, g9624ace
phasehq, [email protected], https://console.internal.tailscale.phase.dev, f6s34az1
🏃 users logout
Logout from the Phase CLI.
Usage:
> phase users logout [--purge]
--purge: Purge all local data. This option will remove any local configuration and data related to the current user's session.
🔐 users keyring
Display information about the Phase keyring. The Phase keyring holds sensitive credentials such as user tokens.
Usage:
> phase users keyring
This command provides insights into the Phase keyring, which is used to securely store user credentials.
📖 docs
Open the Phase Docs in your web browser.
Usage:
> phase docs
This command is a shortcut to quickly access the Phase Docs in your default web browser.
🖥️ console
Open the Phase Console in your web browser.
Usage:
> phase console
This command is a shortcut to quickly access the Phase Console in your default web browser. If you have a .phase.json config in the current working directory, it will automatically open the Console for the app and environment that the config was initialized with.
⌨️ completion
Generate shell autocompletion scripts for the Phase CLI. This allows tab-completion of commands, flags, and arguments in your terminal.
Usage:
> phase completion [shell]
Available sub-commands:
bash— Generate the autocompletion script for bashzsh— Generate the autocompletion script for zshfish— Generate the autocompletion script for fishpowershell— Generate the autocompletion script for powershell
Examples:
# Generate and load zsh completions
> phase completion zsh > "${fpath[1]}/_phase"
# Generate and load bash completions
> phase completion bash > /etc/bash_completion.d/phase
# Generate and load fish completions
> phase completion fish > ~/.config/fish/completions/phase.fish
Run phase completion [shell] --help for detailed instructions for each shell.
🔗 Secret referencing
You can set a value of a secret to a value of another by simply pointing to it via the following syntax.
Secret referencing syntax:
| Value reference syntax | Environment | Path | Secret Key Being Referenced | Description |
|---|---|---|---|---|
${KEY} | same environment | / | KEY | Local reference in the same environment and path root (/). |
${staging.DEBUG} | staging | / (root of staging environment) | DEBUG | Cross-environment reference to a secret at the root (/). |
${production./frontend/SECRET_KEY} | production | /frontend/ | SECRET_KEY | Cross-environment reference to a secret in a specific path. |
${/backend/payments/STRIPE_KEY} | same environment | /backend/payments/ | STRIPE_KEY | Local reference with a specified path within the same environment. |
${backend_api::production.SECRET_KEY} | production (in backend_api app) | / (root of backend_api app) | SECRET_KEY | Cross-application reference to a secret at the root path within another application. |
${backend_api::production./frontend/SECRET_KEY} | production (in backend_api app) | /frontend/ | SECRET_KEY | Cross-application reference to a secret in a specific path within another application. |
For more information see: Phase Console Secrets
Values prefixed with a 🔗 indicate a local secret being referenced, whereas values prefixed with 🌐 indicate a cross-environment secret value being referenced ie. development, staging, prod.
Examples:
Local environment secret referencing:
> phase secrets list --env prod --show
KEY 🗝️ | VALUE ✨
-------------------------------------------------------------------------------------------------
DB_NAME | XP1_LM
DB_USER | j_mclaren
DB_PASSWORD | 6c37810ec6e74ec3228416d2844564fceb99ebd94b29f4334c244db011630b0e
DB_HOST | mc-laren-prod-db.c9ufzjtplsaq.us-west-1.rds.amazonaws.com
DB_PORT | 5432
DATABASE_URL | 🔗 postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}
> phase run "printenv | grep DATABASE_URL"
DATABASE_URL=postgresql://j_mclaren:6c37810ec6e74ec3228416d2844564fceb99ebd94b29f4334c244db011630b0e@mc-laren-prod-db.c9ufzjtplsaq.us-west-1.rds.amazonaws.com:5432/XP1_LM
The database connection string postgresql:// is referencing DB_USER, DB_PASSWORD, DB_HOST, DB_PORT and DB_NAME from the same environment (dev/development)
Local environment secret referencing inside a folder:
The following database credentials are inside of postgres folder
DB_NAME | XP1_LM
DB_USER | j_mclaren
DB_PASSWORD | 6c37810ec6e74ec3228416d2844564fceb99ebd94b29f4334c244db011630b0e
DB_HOST | mc-laren-prod-db.c9ufzjtplsaq.us-west-1.rds.amazonaws.com
DB_PORT | 5432
> phase secrets list --env prod --show
KEY 🗝️ | VALUE ✨
-------------------------------------------------------------------------------------------------
DATABASE_URL | 🔗 postgresql://${postgres/DB_USER}:${postgres/DB_PASSWORD}@${postgres/DB_HOST}:${postgres/DB_PORT}/${postgres/DB_NAME}
> phase run "printenv | grep DATABASE_URL"
DATABASE_URL=postgresql://j_mclaren:6c37810ec6e74ec3228416d2844564fceb99ebd94b29f4334c244db011630b0e@mc-laren-prod-db.c9ufzjtplsaq.us-west-1.rds.amazonaws.com:5432/XP1_LM
The database connection string postgresql:// is referencing DB_USER, DB_PASSWORD, DB_HOST, DB_PORT and DB_NAME from the same environment (dev/development)
Cross environment secret referencing:
> phase secrets list --env prod --show
KEY 🗝️ | VALUE ✨
----------------------------------------------------------------------------
DATABASE_URL | 🌐 postgresql://${dev.DB_USER}:${dev.DB_PASSWORD}@${dev.DB_HOST}:${dev.DB_PORT}/${dev.DB_NAME}
> phase run --env prod "printenv | grep DATABASE_URL"
DATABASE_URL=postgresql://j_mclaren:6c37810ec6e74ec3228416d2844564fceb99ebd94b29f4334c244db011630b0e@mc-laren-prod-db.c9ufzjtplsaq.us-west-1.rds.amazonaws.com:5432/XP1_LM
Note: This is assuming an environment named dev/development exists and has a secrets with the keys AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
Offline mode
The Phase CLI supports offline access to your secrets. After authenticating and fetching secrets at least once, encrypted copies of the API responses are cached locally. If the network becomes unavailable, the CLI can decrypt and serve secrets from this cache.
The offline cache stores encrypted API responses, not plaintext secrets. Decryption happens at read time using key material from your authentication token — the same process as online mode.
Behavior
PHASE_OFFLINE | Caches on success | Serves from cache | Network errors |
|---|---|---|---|
| unset | Yes | No | Fail with PHASE_OFFLINE=1 hint |
1 / true | No (skips network) | Yes | N/A |
0 / false | Yes | No | Fail with PHASE_OFFLINE=1 hint |
How it works
- Automatic caching: Every successful
phase secretscommand transparently caches the encrypted API responses to~/.phase/secrets/offline/. - Explicit offline mode: Set
PHASE_OFFLINE=1to skip network requests entirely and serve directly from cache. This is useful in air-gapped environments or when you know you're offline. - Network errors: If a network request fails and
PHASE_OFFLINEis not set, the CLI will display an error with a hint to setPHASE_OFFLINE=1. It will not silently fall back to cached data.
Cache location
~/.phase/secrets/offline/{account_id}/
userdata.json # encrypted user/app/environment metadata
secrets/
{hash}.json # encrypted secrets (one file per environment + path combination)
Running phase users logout will automatically delete the offline cache for that account.
Dynamic secrets
Dynamic secrets (e.g. short-lived database credentials) require server interaction to generate leases and cannot be served from cache. When offline, the CLI will skip dynamic secrets and log a warning:
⚠️ Offline mode: dynamic secret 'my-db-creds' requires network access, skipping
Write operations
Creating, updating, and deleting secrets require network access. These operations will return an error in offline mode:
> PHASE_OFFLINE=1 phase secrets create MY_KEY=my_value
Error: cannot create secrets in offline mode
Authentication requirement
Offline caching requires a persistent authenticated session via phase auth. This is because the CLI needs a locally stored account identity to scope the cache directory.
When using ad-hoc environment variables (PHASE_SERVICE_TOKEN / PHASE_HOST) without a prior phase auth, caching is not available and PHASE_OFFLINE=1 will have no effect. This is by design — ad-hoc env var authentication is intended for stateless environments like CI/CD where offline mode is not applicable.
To use offline mode with a service account, authenticate first:
> phase auth
# Enter your service account token when prompted
# This persists the identity and enables caching
> phase secrets list
# Secrets are now cached for offline use
Wrapped key share
Offline decryption requires a wrapped key share, which is stored locally after authentication. If you authenticated before this feature was available, simply re-run phase auth to store it****.****
Environment variables
PHASE_DEBUG
Type: Boolean
Description: Set to true to get full tracebacks for error messages
Example:
> PHASE_DEBUG=True phase secrets list
PHASE_HOST
Type: String
Description: A full URL to the REST API of the Phase Service
Example:
> export PHASE_HOST=https://phase.internal.company.domain.com
> phase secrets export
...
PHASE_SERVICE_TOKEN
Type: String
Description: A way to authenticate with the Phase Service via tokens, useful for running the cli in an headless environment like CI/CD, Docker containers etc.
Example:
> export PHASE_SERVICE_TOKEN=pss_service...
> phase secrets export
...
PHASE_VERIFY_SSL
Type: Boolean
Description: A way to temporarily disable TLS certificate verification checks
Note: Disable TLS certificate verification is dangerous and can expose you to risks of MITM attacks.
Example:
> export PHASE_VERIFY_SSL=False
> phase secrets export
...
PHASE_CONFIG_PARENT_DIR_SEARCH_DEPTH
Type: Integer
Description: Sets the maximum depth for searching parent directories for a .phase.json config file when monorepo support is enabled. Default is 8.
Example:
> export PHASE_CONFIG_PARENT_DIR_SEARCH_DEPTH=5
> phase secrets export
...
PHASE_OFFLINE
Type: Boolean
Description: Skip network requests entirely and serve secrets from the local offline cache. Requires that secrets have been fetched at least once while online. See Offline mode below for details.
Example:
> export PHASE_OFFLINE=1
> phase secrets list
...