Machine User Setup (Optional)
The quick start calls the Admin App API as a machine user, authenticated
with a service-account (machine-to-machine) token obtained via the OAuth2
client_credentials grant. This is required because the Admin App has no
password endpoint — human login goes through the OIDC provider's browser flow,
so the bootstrap user's username and password cannot be passed to a script.
Machine-to-machine authentication currently works with Keycloak only.
You normally do not need this page. run.ps1 runs bootstrap.ps1, which
provisions the Keycloak machine client and seeds the machine user
automatically. Use this page when you want to configure the identity provider
by hand.
Setup Keycloak machine account (manually)
If you prefer to configure Keycloak manually instead of running the bootstrap script, follow the steps below.
On the Docker stack this is already done: the bundled edfiadminapp-machine
service-account client/secret and carries all the required info. On other deployments (e.g. IIS-hosted) the machine client is
not present unless you add it — do the steps below once, in the edfi
realm. See also the Admin App's compose/readme.md ("Machine-to-Machine
Authentication").
1. Create the login:app client scope
- In the Keycloak admin console, select the
edfirealm - Go to Client scopes in the left sidebar
- Click Create client scope
- Fill in:
- Name:
login:app - Description:
Access to Ed-Fi Admin App API - Type: Default
- Protocol: OpenID Connect
- Include in token scope: ON
- Name:
- Click Save
2. Create the machine client
- Go to Clients in the left sidebar
- Click Create client
- General Settings:
- Client type: OpenID Connect
- Client ID:
edfiadminapp-machine - Click Next
- Capability config:
- Client authentication: ON
- Authorization: OFF
- Authentication flow: check only Service accounts roles (uncheck "Standard flow" and "Direct access grants")
- Click Next
- Login settings: leave empty and click Save
- On the client's Credentials tab, copy the Client Secret — this is the
value to use as
MACHINE_CLIENT_SECRET
Importing the client JSON silently drops serviceAccountsEnabled — if you
imported the bundled JSON instead of creating the client manually, re-enable
Service accounts roles on the client afterward, or the token request returns
401 unauthorized_client ("Client not enabled to retrieve service account").
3. Add the protocol mappers
Navigate to the client's Client scopes tab, click edfiadminapp-machine-dedicated, then Add mapper → By configuration, and add:
- An Audience mapper:
- Name:
machine-client-audience - Included Custom Audience:
edfiadminapp-api - Add to access token: ON
- Name:
- A User Session Note mapper (lets the Admin App resolve the machine user):
- Name:
client-id-mapper - User Session Note:
clientId - Token Claim Name:
client_id - Claim JSON Type: String
- Add to ID token: ON
- Add to access token: ON
- Name:
Use Included Custom Audience = edfiadminapp-api on the audience mapper,
not "Included Client Audience" (there is no client by that name, so the latter
adds nothing).
4. Assign the client scopes
- On the client's Client scopes tab, click Add client scope, select
login:app, and add it as Default — this putsscope = login:appin the token - On the same tab, change the built-in
rolesscope's Assigned type from Default to Optional
Setting the roles scope to Optional is required. Otherwise Keycloak's
Audience Resolve mapper adds a second account audience, making aud an array
— and the Admin App requires aud to be the single value edfiadminapp-api.