Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Auth GClasses

Authentication, authorization, and OAuth 2.

Source: kernel/c/root-linux/src/c_authz.c, c_auth_bff.c, c_idp_keycloak.c, c_task_authenticate.c


C_AUTHZ

Authorization manager — maintains a JSON Web Key Set (JWKS), verifies JWT tokens, and manages users and their access rules.

PropertyValue
StatesST_STOPPED, ST_IDLE

Commands

CommandDescription
list-jwk / add-jwk / remove-jwkManage JSON Web Keys: list the running set, or change it until the yuno restarts. The persistent set is the config’s (Authz.jwks).
users / create-user / update-user / enable-user / disable-user / delete-userUser management. A role given to create-user / update-user is a ref roles^<role id>^users to a role that exists; anything else is refused before the user is written (“Role does not exist”, “Bad role ref, expected roles^ROLE^users”), and the user keeps the roles it had. Example: ycommand -c 'command-yuno id=<id> service=authz command=update-user username=ana@example.com role=roles^operator^users'. On a replica every write is refused (“READ-ONLY replica”), the commands AND the events: EV_ADD_USER and EV_IDP_USER_CREATED return -1 and log “READ-ONLY replica, the users store cannot be written here” (after 7.25.3).
enable-user / disable-user / set-max-sessionsWrite ONE column of the user -- disabled, or max_sessions -- and nothing else; disable-user also drops the user’s live sessions, and set-max-sessions without username sets the service default max_sessions_per_user. Until 7.25.4 they wrote back the whole view they had read, whose hidden credentials is a null mask, and so ERASED the user’s local password. Example: ycommand -c 'command-yuno id=<id> service=authz command=set-max-sessions username=ana@example.com max_sessions=3'.
accessesList access rules.

Every command from a peer asks a permission of the users treedb (treedb_authzs), whatever enable_command_authz says: read to list, create / update / delete to manage users (create-user with a role asks update too, as link-nodes does), update for the JWKs, set-max-sessions and check-user-pwd. Without it the answer is -403. Up to 7.25.21 they were SDF_AUTHZ_X only, which does nothing while the gate is off: any user the entry gate let in managed users and the trusted signing keys. tests/c/command_delete_user, case 12.

Every comment starts with the yuno that answers (new after 7.25.4; in 7.25.4 “User enabled: x”, “Set max_sessions: ...” and “User not found” did not): command-yuno id=<id> service=authz command=enable-user username=pepe@example.com answers 0: <role^name>: User enabled: pepe@example.com, and an unknown user -1: <role^name>: User not found: 'nobody@example.com'. A failure says its own cause and points at the log, e.g. <role^name>: cannot hash the password of user 'pepe@example.com' (see the log): create-user, update-user and set-user-pwd answered gobj_log_last_message(), the process-global buffer of the last ERROR of anybody. The test walks C_AUTHZ’s command table (tests/c/command_delete_user, case 11).

master is configuration, default false, never set by the service. With an empty tranger_path the path is built from authz_service (or the yuno role), the realm and authz_tenant; only a master creates the directory. A yuno that owns its users says so -- the agent, in its main.c:

'global': {
    'Authz.master': true,
    'Authz.authz_service': 'agent'
}

Without it, a store that does not exist gives “No authz db, authz only to local access” and no treedb, and a store another yuno owns is opened as a READ-ONLY replica.

with_link_events (SDF_RD, default 1, new in 7.26.0) is copied to the C_NODE of treedb_authzs: a link of a user to a role publishes EV_TREEDB_NODE_LINKED, not the role’s EV_TREEDB_NODE_UPDATED. A yuno whose v1 SPA edits treedb_authzs turns it off in its config:

{"name": "authz", "gclass": "C_AUTHZ", "kw": {"with_link_events": false}}

C_AUTH_BFF

Backend-For-Frontend OAuth 2 server — mediates between browser SPAs and Keycloak, storing tokens in httpOnly cookies.

PropertyValue
StatesST_STOPPED, ST_IDLE, ST_WAIT_RESPONSE

Key attributes

AttributeTypeDescription
keycloak_urlstringKeycloak server URL.
realmstringKeycloak realm name.
client_idstringOAuth 2 client ID.
client_secretstringOAuth 2 client secret.
cookie_domainstringDomain for httpOnly cookies.
allowed_originstringCORS allowed origin.
allowed_redirect_uristringAllowed redirect URI after login.
cryptojsonTLS configuration.

Endpoints

EndpointDescription
POST /auth/loginStart login flow.
POST /auth/callbackHandle OAuth callback.
POST /auth/refreshRefresh access token.
POST /auth/logoutLogout and clear cookies.

C_IDP_KEYCLOAK

Manages the ACCOUNTS of a Keycloak identity provider through its admin REST API: create, list, read, change, delete, and email the user the link to set the password. It is not part of C_AUTHZ, which answers one question (does this user hold this permission); managing an external provider is another responsibility, with other credentials, another transport and other failure modes. Instantiated as the service idp, with neutral command names (list-idp-users, not list-kc-users): a second provider would be a sibling gclass serving the same commands, chosen in configuration.

The seam is an event. When it creates an account it publishes EV_IDP_USER_CREATED (username, first_name, last_name, role, idp_user_id), and each plane provisions itself -- C_AUTHZ writes the authorization node. delete-idp-user does NOT touch the local authz record.

One request at a time. Every command enters one queue and one volatile C_TASK drives it through the shared HTTP client; the admin token is job 0 and is skipped while the cached one is fresh. The queue holds 32: a caller beyond that is refused, never left waiting.

PropertyValue
Serviceidp
Output eventEV_IDP_USER_CREATED (optional subscribers)
Trace levelsmessages -- the requests and answers of the admin API

Attributes

The connection is configured at run time with set-kc-config, which saves it (persistent attributes): the values are per deployment and the secret never goes into code or committed configuration.

AttributeTypeDescription
kc_base_urlstringKeycloak base URL (persistent).
kc_realmstringRealm where the accounts live (persistent).
kc_admin_client_idstringConfidential admin client, client_credentials, role manage-users (persistent).
kc_admin_client_secretstringIts secret (persistent; view-kc-config masks it).
kc_redirect_uristringredirect_uri of the set-password email (persistent).
kc_email_client_idstringClient the email links to: the SPA’s (persistent).
kc_cryptojsonTLS of the calls to Keycloak. Verifies by default against the system CA; a private CA is {"ssl_trusted_certificate": "/path/ca.pem"}. mbedTLS has no system store: set ssl_trusted_certificate there.
kc_timeout_msintegerWatchdog of one round trip, default 30000.

Commands

CommandPermissionDescription
set-kc-configconfigure-kcSet and save the connection; only the parameters passed change.
view-kc-configconfigure-kcShow it, secret masked.
register-idp-userregister-idp-userCreate an account (email required, used as username; firstName, lastName). The user gets the email to set the password. Publishes EV_IDP_USER_CREATED. role is legacy: roles belong to the authorization plane, which applies its default_role. A role given by a peer needs, besides register-idp-user, the update of treedb_authzs that create-user asks to link one (else -403).
list-idp-usersmanage-idp-usersList the accounts: search (username, names, email), paging first / max (default 50, ceiling 500), brief=0 for the full representation.
get-idp-usermanage-idp-usersOne account, by user_id (the uuid Keycloak gives, not the email).
update-idp-usermanage-idp-usersChange firstName, lastName, enabled, emailVerified, requiredActions; an absent parameter is left unchanged.
delete-idp-usermanage-idp-usersDelete the account in the IdP. The local authz record is not touched.
send-idp-user-actionsmanage-idp-usersEmail the user the link to run actions (default ["UPDATE_PASSWORD"]; e.g. VERIFY_EMAIL).

user_id also answers to id, which is unusable through command-yuno (the agent reads id as the yuno to address).

Example

The service in a yuno’s main.c, and its first configuration:

{                                                               \n\
    'name': 'idp',                                              \n\
    'gclass': 'C_IDP_KEYCLOAK',                                 \n\
    'autostart': true                                           \n\
},                                                              \n\
ycommand -c "command-yuno id=1620 service=idp command=set-kc-config \
    kc_base_url=https://auth.example.com kc_realm=example \
    kc_admin_client_id=yuneta-admin kc_admin_client_secret=<secret> \
    kc_redirect_uri=https://app.example.com/ kc_email_client_id=app"
ycommand -c "command-yuno id=1620 service=idp command=register-idp-user email=ana@example.com firstName=Ana"
ycommand -c "command-yuno id=1620 service=idp command=list-idp-users search=ana"

Details of the provisioning flow: YUNO_AUTH.md.


C_TASK_AUTHENTICATE

OAuth 2 authentication task — handles the Keycloak authentication flow and caches tokens.

PropertyValue
StatesST_STOPPED, ST_DISCONNECTED, ST_WAIT_CONNECTED, ST_WAIT_RESPONSE, ST_AUTHENTICATED

Key attributes

AttributeTypeDescription
urlstringKeycloak token endpoint URL.
jwtstringCached JWT token (read-only).