Skip to content
Crow CI

Integrations

Crow CI supports external secret store integrations, allowing you to fetch secrets directly from services like HashiCorp Vault or OpenBao during pipeline execution.

While Crow CI provides a built-in secret store using from_secret, integrations enable you to:

  • Centralize secret management across your infrastructure
  • Use existing secret rotation policies
  • Leverage enterprise secret management features
  • Access secrets without duplicating them in Crow CI
TypeDescription
vaultHashiCorp Vault / OpenBao via AppRole authentication
azure_key_vaultAzure Key Vault via Service Principal authentication
infisicalInfisical via Universal Auth (Machine Identity)
  1. Navigate to Integrations in the sidebar

  2. Click Add integration

  3. Configure the integration:

    • Name: A descriptive name for the integration
    • Type: Select the integration type (e.g., HashiCorp Vault)
    • Configuration: Provider-specific settings (see below)
  4. Configure access control via allowlists (users, organizations, or repositories that can use this integration)

  5. Click Save to create the integration

When configuring a Vault integration, provide the following settings:

SettingRequiredDescription
Vault AddressYesFull URL to your Vault server
Role IDYesAppRole Role ID for authentication
Secret IDYesAppRole Secret ID for authentication
Auth PathNoMount path for AppRole auth (default: approle)
Mount PathNoSecrets engine mount path (default: secret)
NamespaceNoVault Enterprise namespace (leave empty for OSS)
Skip TLS VerifyNoSkip TLS certificate verification (not recommended for production)
CA CertificateNoCustom CA certificate for TLS verification

To configure AppRole authentication in Vault:

Terminal window
# Enable AppRole auth method
vault auth enable approle
# Create a policy for Crow CI
vault policy write crow-ci - <<EOF
path "secret/data/crow/*" {
capabilities = ["read"]
}
EOF
# Create an AppRole
vault write auth/approle/role/crow-ci \
token_policies="crow-ci" \
token_ttl=1h \
token_max_ttl=4h
# Get the Role ID
vault read auth/approle/role/crow-ci/role-id
# Generate a Secret ID
vault write -f auth/approle/role/crow-ci/secret-id

When configuring an Azure Key Vault integration, provide the following settings:

SettingRequiredDescription
Vault URLYesFull URL to your Key Vault (e.g., https://my-vault.vault.azure.net)
Tenant IDYesAzure AD (Entra ID) Tenant ID
Client IDYesService Principal Application (Client) ID
Client SecretYesService Principal Client Secret

To configure a Service Principal for Crow CI:

Terminal window
# Create a Service Principal
az ad sp create-for-rbac --name crow-ci --skip-assignment
# Note the appId (Client ID), password (Client Secret), and tenant (Tenant ID)
# Grant the Service Principal access to your Key Vault
az keyvault set-policy \
--name my-vault \
--spn <appId> \
--secret-permissions get list

Alternatively, if using Azure RBAC for Key Vault access control, assign the Key Vault Secrets User role:

Terminal window
az role assignment create \
--role "Key Vault Secrets User" \
--assignee <appId> \
--scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault-name>

Azure Key Vault secrets are single-valued (each secret name maps to one value), unlike Vault’s key-value pairs. Use path for the secret name and set key to "value" by convention:

steps:
- name: deploy
image: alpine
environment:
DB_PASSWORD:
from_secret:
integration: "my-azure-kv"
path: 'prod-db-password' # Azure Key Vault secret name
key: 'value' # Convention for single-valued secrets

When configuring an Infisical integration, provide the following settings:

SettingRequiredDescription
Site URLYesYour Infisical instance URL (default: https://app.infisical.com)
Client IDYesMachine Identity Client ID
Client SecretYesMachine Identity Client Secret
Project IDYesThe Infisical project ID where secrets are stored
EnvironmentYesEnvironment slug (e.g., dev, staging, prod)
Secret PathNoFolder path for secrets (default: /)
  1. In Infisical, go to Organization Settings > Machine Identities and create a new identity

  2. Under the identity, add Universal Auth and note the Client ID and Client Secret

  3. Go to your Project Settings > Access Control > Machine Identities, add the identity, and assign the Viewer role (or a custom role with read access)

  4. Note your Project ID from the project’s URL or settings page

Infisical secrets are scoped by project, environment, and path (configured in the integration). Use path for the secret key name and set key to "value" by convention:

steps:
- name: deploy
image: alpine
environment:
DB_PASSWORD:
from_secret:
integration: "infisical-prod"
path: 'DATABASE_PASSWORD' # Infisical secret key name
key: 'value' # Convention for single-valued secrets

Both internal (Crow CI) and external (Vault, Azure Key Vault, Infisical) secrets use the same from_secret keyword. The difference is in the value:

  • String value = internal secret (from Crow CI’s secret store)
  • Object value = external secret (from an integration like Vault)
steps:
- name: deploy
image: alpine
environment:
# Internal secret from Crow CI
API_KEY:
from_secret: my_api_key
steps:
- name: deploy
image: alpine
environment:
# External secret from Vault
API_KEY:
from_secret:
integration: 1 # Integration ID or name
path: 'crow/myapp'
key: 'api_key'
FieldRequiredDescription
integrationYesIntegration ID (number) or name (string)
pathYesSecret path (Vault), secret name (Azure Key Vault), or key name (Infisical)
keyYesKey within the secret (Vault) or "value" (Azure Key Vault, Infisical)
versionNoSpecific version to fetch (default: 0 = latest)

You can reference integrations by their name for better readability:

steps:
- name: deploy
image: alpine
environment:
API_KEY:
from_secret:
integration: "vault-prod" # Use integration name instead of ID
path: 'crow/myapp'
key: 'api_key'

External secrets work in both environment and settings:

steps:
- name: publish
image: codefloe.com/crowci/buildx:latest
settings:
registry: registry.example.com
repo: myorg/myapp
tags: <your-tag>
username: myuser
password:
from_secret:
integration: 1
path: 'crow/docker'
key: 'password'

Integrations use allowlists to control which pipelines can access secrets:

  • User allowlist: Specific users who can use this integration
  • Organization allowlist: All repositories in specified organizations
  • Repository allowlist: Specific repositories

You can use both internal and external secrets in the same pipeline:

steps:
- name: build
image: alpine
environment:
# Internal secret from Crow CI (string value)
INTERNAL_TOKEN:
from_secret: my_token
# External secret from Vault (object value)
EXTERNAL_API_KEY:
from_secret:
integration: "vault-prod"
path: 'crow/api'
key: 'key'

External secret fetching uses strict error handling:

  • If the external secret store is unreachable, the pipeline fails immediately
  • If a secret path or key doesn’t exist, the pipeline fails with a clear error
  • There are no silent fallbacks to prevent security issues

Best practices:

  • Use dedicated AppRoles with minimal permissions
  • Enable secret rotation in your Vault instance
  • Limit integration access via allowlists
  • Avoid logging secret values in pipeline output
  • Use TLS and verify certificates in production

After creating an integration, use the Test Connection button to verify connectivity:

  • Tests authentication (AppRole for Vault, Service Principal for Azure Key Vault, Universal Auth for Infisical)
  • Verifies network connectivity to the secret store
  • Does not access any actual secrets

A successful test shows “Connection test successful”.