OAuth OCID is used for authentication and authorization in ModelOps. Keycloak is used as an identity provider (IdP) and federation to a customers IdP. This means that all communications with ModelOps APIs use JWT tokens regardless of the customer IdP used (AD, LDAP, Kerberos, OAuth, etc)

Service User

The AOA requires a service user account to be provisioned and configured. This service user is required to communicate from the asynchronous processes which build and execute the docker containers for training, evalation, deployment etc and the APIs. This service user needs to be configured as an admin user as described in the roles.


We only have two roles. A basic role and an admin role.


Admin users have unix like super user privileges and they can access all projects and perform all functions. The only thing they cannot do is view or use users personal dataset connections. We currently identify admin users by the fact that they are part of a special admin group which is configured via

Regular users (non admin) require to be a member of the AD group which is defined for each project in order to access the project. Each project has an associated security group and a user must be part of that group to be able to see anything related to the project. A user can be a member of many groups (security groups) which decide which projects they can access.

API and UI domains

When the service is deployed with a different domains for endpoints of UI and Core API one needs to configure cookie domain, so cookies from backend could used on frontend:

The fact that we support multiple projects, each with its own access control and models repository means that each API request must specify the project we want to access. We support two approaches for this for maximum flexibility. One is to specify the project in the header, this is particularly usefull for UI apps where the user can select the default project and it is sent with each request.

curl -H "AOA-Project-ID: 23e1df4b-b630-47a1-ab80-7ad5385fcd8d" ..

The other option is to append it as a query parameter. This is picked up regardless of the controller or API endpoint as we do it in the ProjectFilter.

curl ..?projectId=23e1df4b-b630-47a1-ab80-7ad5385fcd8d

Dataset Connections

Dataset connection credentials are stored encrypted in the database. We never show the unencrypted versions to users and the credentials are decrypted at runtime when they are used by the jobs for training, evaluation, scoring etc. In deployments using docker-compose, the credentials are provided via env files which are created for each job and attached to the docker containers. Standard security practices around who should have access to this machine and the groups/permissions of these files should be followed (i.e. docker-compose should run as the appropriate user). In the cloud deployments, we create kubernetes secrets and attach these to the pods. Standard kubernetes security practices around secrets apply.

They encrypted and decrypted using a password and the AES-GCM algorithm. This password must be provided as an env variable AOA_CONN_ENCRYPTION_TOKEN in two places:

  • The aoa-core service where they are encrypted

  • The CI service where they are decrypted

Note that this password can not have any spaces, e.g.