Secret Stores
Integrate with external secret management systems to securely inject secrets into server configurations.
Introduction
Secret stores are read-only sources of secrets, allowing you to integrate Gatana with your organization's secret management infrastructure. Instead of storing sensitive credentials directly in Gatana, you can reference secrets from external providers like AWS Secrets Manager, Google Cloud Secret Manager, HashiCorp Vault, Infisical, or Azure Key Vault.
Secrets from external stores can be used anywhere you would use credentials:
- HTTP headers
- Environment variables
- Command arguments
- Remote MCP URLs
Additionally to those values, secrets also be used in:
- Client ID & Client Secret in a server's OAuth authorization configuration
Supported Providers
Gatana supports four external secret store providers:
- AWS Secrets Manager
- GCP Secret Manager
- HashiCorp Vault
- Infisical
- Azure Key Vault
Using Secrets
Reference secrets in your server configurations using the syntax:
{{ secrets.STORE_NAME.MY_SECRET_MAPPING }}Secrets can also be accessed directly without creating a mapping:
{{ secrets.STORE_NAME.[arn:aws:secretsmanager:us-east-1:123456789:secret:my-secret] }}How It Works
- Configure a Secret Store: Connect Gatana to your external secret provider with the necessary credentials.
- Create Secret Mappings: Map friendly names to secret identifiers in your external store.
- Reference Secrets: Use the
{{ secrets.store_name.secret_name }}syntax in your server configurations.
When a server needs a secret, Gatana fetches it from the external store at runtime. Secrets are cached for 1 minute to improve performance.
Configuring Secret Stores
AWS Secrets Manager
{
"name": "my_aws_store",
"type": "aws_secrets_manager",
"configuration": {
"region": "us-east-1",
"accessKeyId": "AKIA...",
"secretAccessKey": "..."
}
}The IAM user or role must have secretsmanager:GetSecretValue permission for the secrets you want to access. To give Gatana access to all secrets, attach the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessAllSecrets",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "*"
}
]
}For more restrictive access, scope the policy to specific secret ARNs:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessSpecificSecrets",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:secretsmanager:us-east-1:123456789012:secret:gatana/*"
]
}
]
}GCP Secret Manager
{
"name": "my_gcp_store",
"type": "gcp_secret_manager",
"configuration": {
"projectId": "my-project-id",
"serviceAccountKey": "{...}"
}
}The serviceAccountKey should be the JSON key file contents for a service account. The service account must have the Secret Manager Secret Accessor role (roles/secretmanager.secretAccessor).
To grant access to all secrets in a project:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/secretmanager.secretAccessor"For more restrictive access, grant the role on specific secrets:
gcloud secrets add-iam-policy-binding SECRET_NAME \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/secretmanager.secretAccessor"HashiCorp Vault
{
"name": "my_vault_store",
"type": "hashicorp_vault",
"configuration": {
"address": "https://vault.example.com",
"token": "hvs.xxx",
"namespace": "admin",
"mountPath": "secret"
}
}| Field | Required | Description |
|---|---|---|
address | Yes | The Vault server URL |
token | Yes | A Vault token with read access to the secrets |
namespace | No | Vault namespace (Enterprise feature) |
mountPath | No | KV secrets engine mount path (defaults to secret) |
Gatana uses the KV v2 secrets engine.
Infisical
{
"name": "my_infisical_store",
"type": "infisical",
"configuration": {
"siteUrl": "https://us.infisical.com",
"accessToken": "...",
"projectId": "...",
"environment": "prod",
"secretPath": "/"
}
}| Field | Required | Description |
|---|---|---|
siteUrl | Yes | Infisical instance URL (e.g. to https://us.infisical.com) |
accessToken | Yes | The access token |
projectId | Yes | The Infisical project ID |
environment | Yes | Environment slug (e.g. prod) |
secretPath | Yes | Path within the project (e.g. /) |
Azure Key Vault
{
"name": "my_azure_store",
"type": "azure_key_vault",
"configuration": {
"vaultUrl": "https://my-vault.vault.azure.net",
"tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"clientSecret": "..."
}
}| Field | Required | Description |
|---|---|---|
vaultUrl | Yes | The Azure Key Vault URL |
tenantId | Yes | Azure AD tenant ID |
clientId | Yes | App registration client ID |
clientSecret | Yes | App registration client secret |
The app registration must have permission to read secrets from the Key Vault. If using Azure RBAC (recommended), assign the Key Vault Secrets User role:
az role assignment create \
--role "Key Vault Secrets User" \
--assignee APP_CLIENT_ID \
--scope /subscriptions/SUBSCRIPTION_ID/resourceGroups/RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/VAULT_NAMEIf using access policies instead of RBAC, grant Get permission for secrets:
az keyvault set-policy \
--name VAULT_NAME \
--spn APP_CLIENT_ID \
--secret-permissions getSecret Mappings
Secret mappings create friendly aliases for secrets in your external stores. This provides several benefits:
- Abstraction: Change the underlying secret without updating server configurations
- Simplified syntax: Use short names instead of ARNs or long paths
- Access control: Only expose specific secrets to Gatana
Creating a Mapping
{
"name": "openai_key",
"secretIdentifier": "arn:aws:secretsmanager:us-east-1:123456789:secret:prod/openai-api-key"
}The secretIdentifier format depends on the provider:
| Provider | Identifier Format |
|---|---|
| AWS Secrets Manager | ARN or secret name |
| GCP Secret Manager | projects/{project}/secrets/{name}/versions/{version} or just the secret name |
| HashiCorp Vault | Path within the mount (e.g., myapp/config) |
| Infisical | The secret key name |
| Azure Key Vault | The secret name |