Skip to content

Store API Keys Securely

Manage sensitive credentials using Azure Key Vault

Store API keys, passwords, and credentials securely in Azure Key Vault. Bifrost automatically encrypts and scopes secrets per organization.

SettingsConfiguration+ Add Config

  • Key: api_key
  • Type: Secret
  • Value: sk_live_xxxxx (your actual secret)

Stores the value encrypted in Key Vault automatically.

from bifrost import config
@workflow(name="call_api")
async def call_api(context: ExecutionContext):
# Get secret (works for both Secret and Secret Reference types)
api_key = await config.get("api_key")
headers = {"Authorization": f"Bearer {api_key}"}
response = await make_api_call(url, headers=headers)
return response

Store third-party API credentials:

@workflow(name="external_api")
async def external_api(context: ExecutionContext):
api_key = await config.get("stripe_api_key")
response = requests.post(
"https://api.stripe.com/v1/charges",
headers={"Authorization": f"Bearer {api_key}"}
)
return response.json()

Store database passwords securely:

@workflow(name="db_query")
async def db_query(context: ExecutionContext):
db_password = await config.get("postgres_password")
conn = await asyncpg.connect(
host="db.example.com",
user="bifrost",
password=db_password,
database="production"
)
result = await conn.fetch("SELECT * FROM users")
await conn.close()
return result

Verify incoming webhooks:

import hmac
import hashlib
@workflow(name="verify_webhook")
async def verify_webhook(context: ExecutionContext, payload: str, signature: str):
webhook_secret = await config.get("webhook_secret")
# Calculate expected signature
expected = hmac.new(
webhook_secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
raise ValueError("Invalid webhook signature")
return {"verified": True}

Secrets are automatically isolated per organization:

  • Org A stores api_key with value sk_live_aaa
  • Org B stores api_key with value sk_live_bbb
  • Workflows automatically use their org’s value
# Automatically uses current org's secret
api_key = await config.get("api_key")

Each organization has completely separate secrets in Key Vault.

  1. SettingsConfiguration
  2. Find config → Click Edit
  3. Enter new value → Save

If using Secret Reference type:

  1. SettingsSecrets
  2. Find secret → Click Edit
  3. Enter new value → Save

All configs referencing this secret automatically use the new value.

✅ Do This:

# Get from Key Vault
api_key = await config.get("api_key")
# Log without exposing value
logger.info("Making API call with stored credentials")
# Don't return in response
return {"success": True, "user_id": user.id}

❌ Don’t Do This:

# Hardcoded secret
api_key = "sk_live_123abc"
# Logged secret value
logger.info(f"API key: {api_key}")
# Returned in response
return {"api_key": api_key}

Always handle missing secrets gracefully:

@workflow(name="safe_api_call")
async def safe_api_call(context: ExecutionContext):
try:
api_key = await config.get("api_key")
except KeyError:
return {
"success": False,
"error": "API key not configured",
"action": "Add 'api_key' to Configuration in Settings"
}
# Use api_key...
return {"success": True}
TypeUse When
SecretOne secret, one config. Simple and direct.
Secret ReferenceReusing secret across multiple configs. Easier rotation.

Example: Secret Reference benefit

Create one secret stripe_key, reference it in multiple configs:

  • stripe_api_key → references stripe_key
  • payment_processor_key → references stripe_key
  • billing_api_key → references stripe_key

Update secret once, all three configs get the new value.

  • Encryption: All secrets encrypted at rest in Azure Key Vault
  • Access Control: RBAC managed through Azure
  • Audit Logs: All secret access is logged
  • Never Exposed: Secrets never returned in API responses or logs
  • Org Isolation: Complete separation between organizations

Config not found: Verify config exists in SettingsConfiguration for your organization.

Permission denied: Ensure Bifrost has Key Vault access. Check Azure Key Vault access policies.

Secret not updating: If using Secret Reference, make sure the referenced secret name is correct.