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
  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

Both internal (Crow CI) and external (Vault) 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)
pathYesPath to the secret in Vault (without the secret/data/ prefix)
keyYesKey within the secret to retrieve
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: codeberg.org/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 AppRole authentication
  • Verifies network connectivity to Vault
  • Does not access any actual secrets

A successful test shows “Connection test successful”.