After installing Formance Enterprise Edition, you need to configure the control plane components: Dex (OIDC provider), Membership (management API), and Console (web interface).
The Membership service is versioned independently from the stack. The admin wizard bootstrap command landed in v2.0.0, so the instructions on this page depend on which Membership release the Helm chart you're installing ships. Pick yours below.
Components Overview#
| Component | Description | Default URL |
|---|---|---|
| Dex | OIDC/OAuth2 provider for authentication | dex.<your-domain> |
| Membership | Management API for organizations, users, and stacks | membership.<your-domain> |
| Console | Web interface for managing your Formance stack | console.<your-domain> |
Dex Configuration#
Dex is deployed as the default OIDC provider. You can configure it to:
- Create local users for testing
- Connect to external identity providers (SAML, LDAP, OAuth2)
- Integrate with your existing SSO infrastructure
Default Configuration#
The default Dex configuration creates a simple setup for testing with a static admin user. For production, configure your own identity provider.
Connecting to External Identity Providers#
Dex configuration is set through cloudprem.membership.dex.configOverrides, which merges with the default Dex configuration generated by the Membership chart.
Using Your Own OIDC Provider#
If you already have an OIDC provider (e.g., Keycloak), you can bypass Dex entirely:
# values.yaml
global:
platform:
membership:
relyingParty:
scheme: "https"
host: "keycloak.example.com"
path: "/realms/master"
cloudprem:
membership:
dex:
enabled: false
config:
oidc:
clientId: "membership"
clientSecret: "your-client-secret"
scopes:
- openid
- email
- federated:idThe global.platform.membership.relyingParty defines the OIDC issuer URL. Use the path field when your provider uses a sub-path (e.g., Keycloak realms).
Membership Configuration#
You can customize authentication behavior and stack defaults:
cloudprem:
membership:
config:
oidc:
clientId: "membership"
clientSecret: "changeMe"
scopes:
- openid
- email
- federated:id
auth:
loginWithSSO: false # Enable email-based SSO selector
tokenValidity:
accessToken: "5m"
refreshToken: "72h"
stack:
minimalStackModules:
- Auth
- Ledger
- Gateway
additionalModules:
- Payments
- Stargate
fctl: true # Enable fctl CLI supportService Ports#
| Service | Port | Protocol |
|---|---|---|
| Membership | 8080 | HTTP |
| Membership | 8082 | gRPC |
| Dex | 5556 | HTTP |
| Portal | 3000 | HTTP |
| Console V3 | 3000 | HTTP |
Initial Setup with Membership CLI#
The Membership CLI provides commands to configure your self-hosted deployment. You run these commands directly inside the Membership container.
Accessing the Membership CLI#
Connect to the Membership container:
kubectl exec -it -n formance-system deployment/membership -- shBootstrap with the wizard#
Membership ships a single admin wizard command that creates the resources you need to get a fresh deployment running — users, organizations, private regions, and stacks. It runs either interactively or against a YAML config you supply, and the chart embeds the same config path so the install job can run it automatically on first boot.
Interactive#
membership admin wizardThe wizard prompts you through a menu — create user, manage organizations, manage private regions, manage stacks. Each step asks for the inputs it needs (email, name, base URL, modules). Use this when you want a one-off setup with no values file changes.
From a config file (idempotent)#
For repeatable installs, declare the resources in a YAML file and pass it with --config:
membership admin wizard --config /path/to/wizard.yaml# wizard.yaml
wizard:
users:
- id: "admin-uuid"
email: "admin@your-company.com"
role: "ADMIN"
organizations:
- id: "my-org"
ownerId: "admin-uuid"
name: "My Company"
# Built-in policy ID applied to users who join the org without an explicit
# policy assignment. 10 = OrganizationAdminStackAdmin, 8 = OrganizationAdmin,
# 4 = OrganizationGuest, etc. See "Built-in policies" in /manage/identity/rbac.
defaultPolicyId: 10
regions:
- id: "region-1"
name: "default"
baseUrl: "https://formance.your-domain.com"
organizationId: "my-org"
stacks:
- id: "production"
name: "production"
organizationId: "my-org"
regionId: "region-1"
version: "v3.1"
modules: ["Auth", "Ledger", "Gateway"]The wizard reconciles each section idempotently: existing resources are checked against the config (and the wizard errors out if there's a mismatch), missing resources are created. Re-running with the same config is safe.
User-level role is the system role (whether the user is a platform admin), distinct from the org-level RBAC policy assigned via defaultPolicyId:
ADMIN— full system accessUSER— standard access
The chart embeds this same YAML directly under cloudprem.membership.config.wizard.setup in your values.yaml and runs the wizard job once on first install — see Wizard Bootstrap (Alternative to CLI) below for the values-file variant used by the ee-demo.yaml profile.
Available commands#
The full membership CLI surface:
membership
├── serve # Run the membership HTTP service
├── version # Print version info
├── storage
│ └── migrations # Database migration commands
├── admin
│ └── wizard # Interactive or config-driven bootstrap
├── stargate # Stargate relay service
├── stream # Internal event-stream commands
├── cycle # Stack-cycle worker
├── gc # Garbage collection
└── report # Reporting toolsRun membership <command> --help to see flags for any subcommand.
Configure Organization with fctl#
After the initial setup, you can use fctl for additional configuration.
Login to Your Cluster#
fctl login --membership-uri https://membership.<your-domain>/apiConfigure Auto-Login for Your Domain#
fctl cloud organizations update <ORGANIZATION_ID> \
--domain=your-company.com \
--default-organization-role=GUEST \
--default-stack-role=GUESTWizard Bootstrap (Alternative to CLI)#
Instead of using the Membership CLI, you can auto-create users, organizations, regions, and stacks on first install using the wizard in your values file:
cloudprem:
membership:
dex:
configOverrides:
staticPasswords:
- email: "admin@example.com"
hash: "$2a$10$..." # bcrypt hash of password
username: "admin"
userID: "unique-uuid"
role: ADMIN
config:
wizard:
setup: |
users:
- id: "unique-uuid"
email: "admin@example.com"
role: "ADMIN"
organizations:
- id: "my-org"
ownerId: "unique-uuid"
name: "My Organization"
regions:
- id: "region-1"
name: "production"
organizationId: "my-org"
baseUrl: "https://formance.example.com"
stacks:
- id: "main"
name: "main"
organizationId: "my-org"
regionId: "region-1"
version: "v3.1"The wizard job runs once on first install and creates all the configured resources. This is the approach used by the ee-demo.yaml profile.
Accessing the Console#
After setup, access the Console at:
https://console.<your-domain>Log in with your configured identity provider credentials.
Verifying the Setup#
Check Component Health#
# Check all pods are running
kubectl get pods -n formance-system
# Check services
kubectl get svc -n formance-system
# Check ingresses
kubectl get ingress -n formance-systemTest Authentication#
# Test Dex
curl -I https://dex.<your-domain>/.well-known/openid-configuration
# Test Membership API
curl -I https://membership.<your-domain>/api/_info
# Test Console
curl -I https://console.<your-domain>