Import from a file
--from config imports a realm from a FerrisKey-native description file. The format comes from the extension: .yaml, .yml, or .toml. No external system and no credentials are involved.
ferris-ctl realm import --from config --file realm.yaml
Preview without writing anything:
ferris-ctl realm import --from config --file realm.yaml --dry-run -o yaml
Format
A description carries a name, plus optional settings, roles, clients, and users sections. The repository ships a working example at cli/examples/realm.yaml.
name: acme
settings:
access_token_lifetime: 300
refresh_token_lifetime: 1800
user_registration_enabled: true
forgot_password_enabled: true
roles:
- name: admin
description: Realm administrators
permissions:
- manage_realm
- manage_users
- name: viewer
description: Read-only access
permissions:
- view_users
- view_clients
clients:
- client_id: web-app
name: Web Application
client_type: public
public_client: true
redirect_uris:
- https://app.acme.test/callback
- https://app.acme.test/*
- client_id: backend
name: Backend Service
client_type: confidential
service_account_enabled: true
direct_access_grants_enabled: true
roles:
- name: service-reader
description: Service-scoped read role
users:
- username: alice
email: alice@acme.test
firstname: Alice
lastname: Doe
email_verified: true
roles:
- admin
- username: bob
email: bob@acme.test
roles:
- viewer
Settings
Every setting is optional. Anything you leave out keeps the FerrisKey default.
| Field | Description |
|---|---|
default_signing_algorithm | Token signing algorithm |
access_token_lifetime | Access token TTL (seconds) |
refresh_token_lifetime | Refresh token TTL (seconds) |
id_token_lifetime | ID token TTL (seconds) |
temporary_token_lifetime | Temporary token TTL (seconds) |
user_registration_enabled | Allow self-registration |
forgot_password_enabled | Enable the forgot-password flow |
remember_me_enabled | Enable “remember me” |
magic_link_enabled / magic_link_ttl | Magic-link login and its TTL |
passkey_enabled | Enable passkeys |
compass_enabled | Enable the Compass module |
email_verification_enabled | Require email verification |
email_verification_ttl_hours | Email verification link TTL (hours) |
Roles
| Field | Default | Description |
|---|---|---|
name | required | Role name |
description | none | Free-text description |
permissions | [] | Permission names, in snake_case |
Permissions use the names from the permissions reference, so manage_realm, not ManageRealm and not realm:manage. Unrecognized names are dropped silently when the role is created.
Clients
| Field | Default | Description |
|---|---|---|
client_id | required | Client identifier |
name | none | Display name |
client_type | public | public, confidential, or system |
protocol | openid-connect | Protocol used by the client |
enabled | true | Whether the client can be used |
public_client | false | Public client, no secret |
service_account_enabled | false | Create a linked service account user |
direct_access_grants_enabled | false | Allow the password grant |
device_authorization_grant_enabled | false | Allow the device code grant |
redirect_uris | [] | Allowed redirect URIs |
post_logout_redirect_uris | [] | Allowed post-logout redirect URIs |
web_origins | [] | Browser origins allowed on this client’s realm-scoped routes |
require_pkce | inherit | Require PKCE on the authorization code flow |
access_token_lifetime | inherit | Override the realm access token TTL, in seconds |
refresh_token_lifetime | inherit | Override the realm refresh token TTL |
id_token_lifetime | inherit | Override the realm ID token TTL |
temporary_token_lifetime | inherit | Override the realm temporary token TTL |
roles | [] | Roles scoped to this client, same shape as realm roles |
Users
| Field | Default | Description |
|---|---|---|
username | required | Username |
email | none | Email address |
firstname | none | First name |
lastname | none | Last name |
email_verified | none | Mark the email as already verified |
roles | [] | Roles to assign |
A plain name in roles refers to a realm role. Prefix it with a client id to pick a role scoped to that client:
users:
- username: alice
roles:
- admin # realm role
- backend:service-reader # role of the "backend" client
Passwords are not in the blueprint
Credentials are never part of an import. Users come out without a password: set one afterwards with ferris-ctl user set-password, from the admin console, or through a recovery flow.