// Metadata created by nebel

[id="registry-security-settings_{context}"]

= {registry} authentication and authorization configuration options

[role="_abstract"]
{registry} provides authentication options for OpenID Connect with {keycloak} and HTTP basic authentication.  

{registry} provides authorization options for role-based and content-based approaches: 

* Role-based authorization for default admin, write, and read-only user roles. 
* Content-based authorization for schema or API artifacts, where only the owner of the artifacts or artifact group can update or delete artifacts. 

IMPORTANT: All authentication and authorization options in {registry} are disabled by default. Before enabling any of these options, you must first set the `QUARKUS_OIDC_TENANT_ENABLED` option to `true`.

This chapter provides details on the following configuration options: 

* xref:registry-security-authn-keycloak[{registry} authentication by using OpenID Connect with {keycloak}]
* xref:registry-security-authn-http[{registry} authentication by using HTTP basic]
* xref:registry-security-rbac-enabled[{registry} role-based authorization] 
* xref:registry-security-obac-enabled[{registry} owner-only authorization] 
* xref:registry-security-auth-read[{registry} authenticated read access] 
* xref:registry-security-anon-read[{registry} anonymous read-only access] 

[discrete]
[id="registry-security-authn-keycloak"]
== {registry} authentication by using OpenID Connect with {keycloak} 

You can set the following environment variables to configure authentication for the {registry} web console and API with {keycloak}:

.Configuration for {registry} authentication with {keycloak}
[.table-expandable,width="100%",cols="5,6,2,4",options="header"]
|===
|Environment variable
|Description
|Type
|Default
|`QUARKUS_OIDC_TENANT_ENABLED`
|Enables authentication for {registry}. When set to `true`, the environment variables that follow are required for authentication using {keycloak}.
|String
|`false`
|`QUARKUS_OIDC_AUTH_SERVER_URL`
|The URL of the {keycloak} authentication server. For example, `\http://localhost:8080`.
|String
|-
|`QUARKUS_OIDC_CLIENT_ID`
|The client ID for the {registry} REST API.
|String
|`registry-api`
|`APICURIO_UI_AUTH_OIDC_CLIENT_ID`
|The client ID for the {registry} web console.
|String
|`apicurio-registry`

|`QUARKUS_OIDC_TLS_TRUST_STORE_FILE`
| Specifies the file path to the TLS trust store used by Quarkus for securing OpenID Connect (OIDC) communications. The trust store can be populated with the trusted certificates needed to establish secure TLS connections with the OIDC provider.
|String
|- 

|`QUARKUS_OIDC_TLS_TRUST_STORE_PASSWORD`
|The password required to access the TLS trust store file. 
|String
|-

|`ROLE_BASED_AUTHZ_ENABLED`
|Enables or disables role-based authorization.
|Boolean
|False

|===

[discrete]
[id="registry-security-authn-http"]
== {registry} authentication by using HTTP basic

By default, {registry} supports authentication by using OpenID Connect. Users or API clients must obtain an access token to make authenticated calls to the {registry} REST API.  However, because some tools do not support OpenID Connect, you can also configure {registry} to support HTTP basic authentication by setting the following configuration options to `true`:

.Configuration for {registry} HTTP basic authentication
[%header,cols="4,4,1,1"]
|===
|Environment variable
|Java system property
|Type
|Default value
|`QUARKUS_OIDC_TENANT_ENABLED`
|`apicurio.auth.enabled`
|Boolean
|`false`
|`CLIENT_CREDENTIALS_BASIC_ENABLED`
|`apicurio.auth.basic-auth-client-credentials.enabled`
|Boolean
|`false`
|===

[discrete]
=== {registry} HTTP basic client credentials cache expiry 

You can also configure the HTTP basic client credentials cache expiry time. By default, when using HTTP basic authentication, {registry} caches JWT tokens, and does not issue a new token when there is no need. You can configure the cache expiry time for JWT tokens, which is set to 10 mins by default. 

When using {keycloak}, it is best to set this configuration to your {keycloak} JWT expiry time minus one minute. For example, if you have the expiry time set to `5` mins in {keycloak}, you should set the following configuration option to `4` mins:

.Configuration for HTTP basic client credentials cache expiry
[%header,cols="4,4,1,1"]
|===
|Environment variable
|Java system property
|Type
|Default value
|`CLIENT_CREDENTIALS_BASIC_CACHE_EXPIRATION`
|`apicurio.auth.basic-auth-client-credentials.cache-expiration`
|Integer
|`10`
|===


[discrete]
[id=registry-security-rbac-enabled]
==  {registry} role-based authorization

You can set the following options to `true` to enable role-based authorization in {registry}:

.Configuration for {registry} role-based authorization
[%header,cols="4,4,1,1"]
|===
|Environment variable
|Java system property
|Type
|Default value
|`QUARKUS_OIDC_TENANT_ENABLED`
|`apicurio.auth.enabled`
|Boolean
|`false`
|`APICURIO_AUTH_ROLE_BASED_AUTHORIZATION`
|`apicurio.auth.role-based-authorization`
|Boolean
|`false`
|===

You can then configure role-based authorization to use roles included in the user's authentication token (for example, granted when authenticating by using {keycloak}), or to use role mappings managed internally by {registry}.

[discrete]
=== Use roles assigned in {keycloak}

To enable using roles assigned by {keycloak}, set the following environment variables:

.Configuration for {registry} role-based authorization by using {keycloak}
[id="registry-security-rbac-keycloak-settings"]
[.table-expandable,width="100%",cols="6,6,2,3",options="header"]
|===
|Environment variable
|Description
|Type
|Default
|`ROLE_BASED_AUTHZ_SOURCE`
| When set to `token`, user roles are taken from the authentication token.
|String
|`token`
|`APICURIO_AUTH_ROLES_ADMIN`
|The name of the role that indicates a user is an admin.
|String
|`sr-admin`
|`APICURIO_AUTH_ROLES_DEVELOPER`
|The name of the role that indicates a user is a developer.
|String
|`sr-developer`
|`APICURIO_AUTH_ROLES_READONLY`
|The name of the role that indicates a user has read-only access.
|String
|`sr-readonly`
|===

When {registry} is configured to use roles from {keycloak}, you must assign {registry} users to at least one
of the following user roles in {keycloak}. However, you can configure different user role names by using the environment variables in xref:registry-security-rbac-keycloak-settings[].

.{registry} roles for authentication and authorization
[.table-expandable,width="100%",cols="2,2,2,2,4",options="header"]
|===
|Role name
|Read artifacts
|Write artifacts
|Global rules
|Description
|`sr-admin`
|Yes
|Yes
|Yes
|Full access to all create, read, update, and delete operations.
|`sr-developer`
|Yes
|Yes
|No
|Access to create, read, update, and delete operations, except configuring global rules and import/export. This role can configure artifact-specific rules only.
|`sr-readonly`
|Yes
|No
|No
|Access to read and search operations only. This role cannot configure any rules.
|===

[discrete]
=== Manage roles directly in {registry}

To enable using roles managed internally by {registry}, set the following environment variable:

.Configuration for {registry} role-based authorization by using internal role mappings
[.table-expandable,width="100%",cols="6,6,2,3",options="header"]
|===
|Environment variable
|Description
|Type
|Default
|`ROLE_BASED_AUTHZ_SOURCE`
| When set to `application`, user roles are managed internally by {registry}.
|String
|`token`
|===

When using internally managed role mappings, users can be assigned a role by using the `/admin/roleMappings`
endpoint in the {registry} REST API.  For more details, see {registry-rest-api}.

Users can be granted exactly one role: `ADMIN`, `DEVELOPER`, or `READ_ONLY`. Only users with admin
privileges can grant access to other users. 


[discrete]
=== {registry} admin-override configuration

Because there are no default admin users in {registry}, it is usually helpful to configure another way for users to be identified as admins. You can configure this admin-override feature by using the following environment variables:

.Configuration for {registry} admin-override 
[.table-expandable,width="100%",cols="6,6,2,3",options="header"]
|===
|Environment variable
|Description
|Type
|Default
|`APICURIO_AUTH_ADMIN_OVERRIDE_ENABLED`
| Enables the admin-override feature.
|String
|`false`
|`APICURIO_AUTH_ADMIN_OVERRIDE_FROM`
|Where to look for admin-override information.  Only `token` is currently supported.
|String
|`token`
|`APICURIO_AUTH_ADMIN_OVERRIDE_TYPE`
|The type of information used to determine if a user is an admin.  Values depend on the value of the FROM variable, for example, `role` or `claim` when FROM is `token`.
|String
|`role`
|`APICURIO_AUTH_ADMIN_OVERRIDE_ROLE`
|The name of the role that indicates a user is an admin.
|String
|`sr-admin`
|`APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM`
|The name of a JWT token claim to use for determining admin-override.
|String
|`org-admin`
|`APICURIO_AUTH_ADMIN_OVERRIDE_CLAIM_VALUE`
|The value that the JWT token claim indicated by the CLAIM variable must be for the user to be granted admin-override.
|String
|`true`
|===

For example, you can use this admin-override feature to assign the `sr-admin` role to a single user
in {keycloak}, which grants that user the admin role.  That user can then use the `/admin/roleMappings`
REST API (or associated UI) to grant roles to additional users (including additional admins).

[discrete]
[id=registry-security-obac-enabled]
== {registry} owner-only authorization

You can set the following options to `true` to enable owner-only authorization for updates to artifacts or artifact groups in {registry}:

.Configuration for owner-only authorization
[%header,cols="4,4,1,1"]
|===
|Environment variable
|Java system property
|Type
|Default value

|`QUARKUS_OIDC_TENANT_ENABLED`
|`apicurio.auth.enabled`
|Boolean
|`false`

|`APICURIO_AUTH_OBAC_ENABLED`
|`apicurio.auth.owner-only-authorization`
|Boolean
|`false`

|`APICURIO_AUTH_OBAC_LIMIT_GROUP_ACCESS`
|`apicurio.auth.owner-only-authorization.limit-group-access`
|Boolean
|`false`
|===

When owner-only authorization is enabled, only the user who created an artifact can modify or delete that artifact.

When owner-only authorization and group owner-only authorization are both enabled, only the user who created an artifact group has write access to that artifact group, for example, to add or remove artifacts in that group.

[discrete]
[id=registry-security-auth-read]
== {registry} authenticated read access

When the authenticated read access option is enabled, {registry} grants at least read-only access to requests from any authenticated user in the same organization, regardless of their user role. 

To enable authenticated read access, you must first enable role-based authorization, and then ensure that the following options are set to `true`:

.Configuration for authenticated read access
[%header,cols="4,4,1,1"]
|===
|Environment variable
|Java system property
|Type
|Default value
|`QUARKUS_OIDC_TENANT_ENABLED`
|`apicurio.auth.enabled`
|Boolean
|`false`
|`APICURIO_AUTH_AUTHENTICATED_READS_ENABLED`
|`apicurio.auth.authenticated-read-access.enabled`
|Boolean
|`false`
|===

For more details, see xref:registry-security-rbac-enabled[].

[discrete]
[id=registry-security-anon-read]
== {registry} anonymous read-only access

In addition to the two main types of authorization (role-based and owner-based authorization), {registry}
supports an anonymous read-only access option.

To allow anonymous users, such as REST API calls with no authentication credentials, to make read-only 
calls to the REST API, set the following options to `true`:

.Configuration for anonymous read-only access
[%header,cols="4,4,1,1"]
|===
|Environment variable
|Java system property
|Type
|Default value
|`QUARKUS_OIDC_TENANT_ENABLED`
|`apicurio.auth.enabled`
|Boolean
|`false`
|`APICURIO_AUTH_ANONYMOUS_READ_ACCESS_ENABLED`
|`apicurio.auth.anonymous-read-access.enabled`
|Boolean
|`false`
|===


[role="_additional-resources"]
.Additional resources
* For an example of how to set environment variables in your {registry} deployment on OpenShift, see xref:configuring-liveness-readiness-probes_{context}[]
* For details on configuring custom authentication for {registry}, the see https://quarkus.io/guides/security-openid-connect-web-authentication[Quarkus Open ID Connect documentation]
