keelconfig.yaml
The keelconfig.yaml file configures your Keel backend. It lives at the root of your project and controls environment variables, secrets, authentication, console settings, hardware integration, and deployment options.
Environment-specific configuration
The configuration in your keelconfig.yaml is used locally when running your application with keel run, but also applies to your staging and production environments.
You can provide different configuration for each environment using:
keelconfig.staging.yamlfor staging environmentskeelconfig.production.yamlfor production environments
If an environment-specific file exists, it completely replaces the default keelconfig.yaml for that environment. Configuration files are not merged, so you must include all required settings in each file.
# This file replaces keelconfig.yaml entirely for staging
environment:
- name: LOG_LEVEL
value: "debug"
secrets:
- name: API_KEY
auth:
providers:
- type: google
name: google_client
clientId: staging-client-idEnvironment variables
Environment variables are values passed to your application at runtime. They're useful for configuration that varies between environments but isn't sensitive.
environment:
- name: EXTERNAL_API_URL
value: "https://staging.some-api.com"
- name: LOG_LEVEL
value: "info"| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Must be UPPER_SNAKE_CASE. Cannot use reserved prefixes (AWS_, KEEL_, OTEL_). |
value | string | No | The value for the environment variable. |
Access environment variables in your functions using ctx.env:
const apiUrl = ctx.env.EXTERNAL_API_URL;See Environment Variables for more details.
Secrets
Secrets store sensitive information like API keys and passwords. You declare secret names in your config, but set their values separately using the CLI or Console.
secrets:
- name: STRIPE_SECRET_KEY
- name: SENDGRID_API_KEY| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Must be UPPER_SNAKE_CASE. Cannot use reserved prefixes (AWS_, KEEL_, OTEL_). |
Set secrets locally using the CLI:
keel secrets set STRIPE_SECRET_KEY sk_test_...For deployed environments, use the Console's Secrets page.
Access secrets in your functions using ctx.secrets:
const stripeKey = ctx.secrets.STRIPE_SECRET_KEY;See Secrets for more details.
Authentication
The auth section configures user authentication, including third-party providers, token settings, identity claims, and hooks.
Basic configuration
auth:
redirectUrl: http://localhost:3000/callback
providers:
- type: google
name: google_client
clientId: your-google-client-idProviders
Configure one or more authentication providers. Keel supports Google, Facebook, GitLab, Slack, and custom OpenID Connect providers.
auth:
providers:
# Built-in Google provider
- type: google
name: google_client
clientId: "1234567890.apps.googleusercontent.com"
# Built-in Facebook provider
- type: facebook
name: fb_login
clientId: "1234567890"
# Built-in GitLab provider
- type: gitlab
name: gitlab_auth
clientId: "abcdef123456"
# Built-in Slack provider
- type: slack
name: slack_login
clientId: "1234.5678"
# Custom OpenID Connect provider
- type: oidc
name: auth0
issuerUrl: "https://your-tenant.auth0.com"
clientId: "your-auth0-client-id"| Property | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Provider type: google, facebook, gitlab, slack, or oidc. |
name | string | Yes | Unique identifier for this provider. Alphanumeric and underscores only. Cannot start with keel_. |
clientId | string | Yes | The OAuth client ID from your provider. |
issuerUrl | string | For oidc | The OpenID Connect issuer URL. Required when type is oidc. Must be HTTPS. |
tokenUrl | string | No | Custom token endpoint URL. Only for type: oidc. |
authorizationUrl | string | No | Custom authorization endpoint URL. Only for type: oidc. |
scopes | string[] | No | Additional OAuth scopes to request. |
For SSO authentication, you'll also need to set the client secret. The secret name follows the pattern AUTH_PROVIDER_SECRET_{NAME} where {NAME} is the provider name in UPPER_SNAKE_CASE:
keel secrets set AUTH_PROVIDER_SECRET_GOOGLE_CLIENT your-client-secretRedirect URL
For Single Sign-On flows, configure where users are redirected after authentication:
auth:
redirectUrl: https://myapp.com/auth/callbackThe redirect URL receives an authorization code in the code query parameter, which you exchange for tokens at the /auth/token endpoint.
Token configuration
Control how long access and refresh tokens remain valid:
auth:
tokens:
# Access token lifespan in seconds (default: 86400 = 24 hours)
accessTokenExpiry: 3600
# Refresh token lifespan in seconds (default: 7776000 = 90 days)
refreshTokenExpiry: 604800
# Enable refresh token rotation (default: true)
refreshTokenRotationEnabled: true| Property | Type | Default | Description |
|---|---|---|---|
accessTokenExpiry | integer | 86400 (24 hours) | How long access tokens remain valid, in seconds. |
refreshTokenExpiry | integer | 7776000 (90 days) | How long refresh tokens remain valid, in seconds. |
refreshTokenRotationEnabled | boolean | true | When enabled, each token refresh issues a new refresh token, invalidating the previous one. |
Keep access tokens short-lived since they provide direct API access. Use refresh tokens to obtain new access tokens without re-authenticating.
Identity claims
Map custom claims from ID tokens to fields on the Identity model. This is useful when your authentication provider includes additional user data you want to store.
auth:
providers:
- type: google
name: google
clientId: "1234"
claims:
- key: "https://myapp.com/team_id"
field: teamId
unique: true
- key: "department"
field: department| Property | Type | Required | Description |
|---|---|---|---|
key | string | Yes | The claim key in the ID token. |
field | string | Yes | The field name on the Identity model to store this value. |
unique | boolean | No | If true, this claim value must be unique across all identities. |
To use identity claims, add corresponding fields to your schema:
model Identity {
fields {
teamId Text? @unique
department Text?
}
}Auth hooks
Execute custom logic during authentication by enabling hooks:
auth:
hooks:
- afterIdentityCreated
- afterAuthentication| Hook | Description |
|---|---|
afterIdentityCreated | Runs when a new Identity is created during authentication. Useful for creating related records like user profiles. |
afterAuthentication | Runs after every authentication attempt, whether successful or not. |
After adding hooks to your config, run keel generate to scaffold the function files in functions/auth/.
See Auth Hooks for implementation details.
Complete auth example
auth:
redirectUrl: https://myapp.com/auth/callback
tokens:
accessTokenExpiry: 3600
refreshTokenExpiry: 604800
refreshTokenRotationEnabled: true
providers:
- type: google
name: google_client
clientId: "1234567890.apps.googleusercontent.com"
scopes:
- openid
- email
- profile
- type: oidc
name: okta
issuerUrl: "https://your-org.okta.com"
clientId: "0oa1234567890abcdef"
claims:
- key: "https://myapp.com/role"
field: role
- key: "org_id"
field: organizationId
unique: true
hooks:
- afterIdentityCreatedSee Authentication for the complete authentication guide.
Console
The console section configures the Keel Console, including which API powers the built-in tools.
console:
api: api| Property | Type | Default | Description |
|---|---|---|---|
api | string | "api" | The name of the API to use for Console tools. Must match an API defined in your schema. |
If you have multiple APIs defined in your schema and want the Console tools to use a specific one:
api Web {
// Public-facing API
}
api Admin {
// Internal admin API with more permissions
}console:
api: AdminHardware
The hardware section registers physical devices like label printers for use in flows. Devices must be named here before they can be referenced in flow components.
hardware:
printers:
- name: shipping-label-printer
- name: packing-slip-printer| Property | Type | Required | Description |
|---|---|---|---|
printers[].name | string | Yes | A unique name for this printer. Used to reference the printer in flows. |
Printer names must be unique within your project. The actual printer mapping (connecting this name to a physical device) happens in the Console under Settings > Devices.
See Hardware Integration for setup instructions.
Default API
Control whether Keel generates a default API for your schema:
useDefaultApi: false| Property | Type | Default | Description |
|---|---|---|---|
useDefaultApi | boolean | true | When true, Keel creates a default Api containing all actions. Set to false if you want to explicitly define which actions belong to which APIs. |
Complete configuration reference
Here's a comprehensive example showing all configuration options:
# Environment variables
environment:
- name: LOG_LEVEL
value: "info"
- name: EXTERNAL_API_URL
value: "https://api.example.com"
# Secrets (values set separately)
secrets:
- name: STRIPE_SECRET_KEY
- name: SENDGRID_API_KEY
# API configuration
useDefaultApi: true
# Authentication
auth:
redirectUrl: https://myapp.com/auth/callback
tokens:
accessTokenExpiry: 3600
refreshTokenExpiry: 604800
refreshTokenRotationEnabled: true
providers:
- type: google
name: google_client
clientId: "1234567890.apps.googleusercontent.com"
claims:
- key: "org_id"
field: organizationId
unique: true
hooks:
- afterIdentityCreated
# Console settings
console:
api: api
# Hardware devices
hardware:
printers:
- name: label-printer