> For the complete documentation index, see [llms.txt](https://docs.seldon.ai/seldon-enterprise-platform/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.seldon.ai/seldon-enterprise-platform/production-environment/authorization.md).

# Authorization

> Configure authorization for Seldon Enterprise Platform and Seldon Core

Authorization is a recommended but **optional** feature. It can be enabled later on, should you choose not to use it initially.

## Seldon Enterprise Platform

### Enable Authorization

To enable OPA authorization in Seldon Enterprise Platform the following values must be set in the `install-values.yaml` file:

```yaml
rbac:
  opa:
    enabled: true
    projectAuthEnabled: true            # Disable if you don't want to authorize project-scoped resources.
    configMap: seldon-deploy-policies   # Change only if you need to use a different ConfigMap name.
  nsLabelsAuth:
    enabled: false                      # Deprecated (leave as false unless instructed otherwise).
```

Seldon Enterprise Platform uses the OPA policies in the given ConfigMap to authorize requests to its API endpoints.

For a detailed explanation of the policy schema and how to set up the ConfigMap, follow the [authorization configuration guide](/seldon-enterprise-platform/operations/authorization.md).

{% hint style="info" %}
**Note**:\
\- Enabling project-based authorization \`rbac.opa.projectAuthEnabled\` requires the Model Catalog to also be enabled. For more details, see the [Postgres setup guide](/seldon-enterprise-platform/production-environment/postgresql.md).\
\- If the specified ConfigMap does not exist, is empty, or does not contain a valid JSON document, Seldon Enterprise Platform does not start. If there are no policies specified, all requests to authorized endpoints are denied.
{% endhint %}

## Seldon Core

{% hint style="info" %}
**Note**: Authorization of direct access to the Seldon Core inference API is only supported with Istio.
{% endhint %}

Access to Seldon Core deployments can be configured to require authorization. Seldon Enterprise Platform does this by managing Istio `AuthorizationPolicy` CRDs. It is assumed that you are running Istio with sidecar injection disabled.

### Enable Authorization

To enable Seldon Enterprise Platform to manage Istio authorization policies, you need to set the Helm parameter `rbac.opa.istioPolicySyncInterval` to a strictly positive duration. The suggested interval is 5 minutes, denoted `5m`.

```yaml
rbac:
  opa:
    istioPolicySyncInterval: "5m"
```

Further information on this parameter can be found in the [operations guide](/seldon-enterprise-platform/operations/authorization.md).

### Istio Setup

#### General Setup

You first need to add a [RequestAuthentication](https://istio.io/latest/docs/reference/config/security/request_authentication/) resource to authenticate incoming requests. The CRD looks like this:

```yaml
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: seldon-authentication
  namespace: istio-system
spec:
  jwtRules:
    - issuer: {{ REPLACE_ME_TOKEN_ISSUER }}
      jwksUri: {{ REPLACE_ME_URI_FOR_TOKEN_ISSUER_JWKS }}
      forwardOriginalToken: true
```

* `REPLACE_ME_TOKEN_ISSUER` must be the same as the issuer field for tokens used to access Seldon Enterprise Platform.
* `REPLACE_ME_URI_FOR_TOKEN_ISSUER_JWKS` is the URI from which Istio can fetch the issuer's JWKS in order to verify the incoming requests' tokens. Alternatively, you can use the JWKS directly using `jwks` instead of `jwksUri` in the `jwtRules` section of the CRD as described in the [official documentation](https://istio.io/latest/docs/reference/config/security/request_authentication/#JWTRule).

Then you can add a couple of policies to allow token-less access to the rest of the platform, but forbid requests with no token to Seldon Core deployments. The policies can be modified to better fit your platform needs.

```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-all-with-no-jwt
  namespace: istio-system
spec:
  action: ALLOW
  rules:
    - from:
        - source:
            notRequestPrincipals:
              - '*'
  selector:
    matchLabels:
      app: istio-ingressgateway
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-empty-jwt-to-seldon
  namespace: istio-system
spec:
  action: DENY
  rules:
    - from:
        - source:
            notRequestPrincipals:
              - '*'
      to:
        - operation:
            paths:
              - /seldon/*
  selector:
    matchLabels:
      app: istio-ingressgateway
---
```

#### Keycloak Setup

If using Keycloak in the same cluster as Seldon Enterprise Platform, the configuration is slightly different to allow access to Keycloak for authentication or user management.

The `RequestAuthentication` resource now has two issuer rules: one for Seldon, as before, and another for Keycloak administrative access.

```yaml
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: keycloak-authentication
  namespace: istio-system
spec:
  jwtRules:
    - issuer: {{ REPLACE_ME_KEYCLOAK_ADDRESS }}/auth/realms/deploy-realm
      jwksUri: {{ REPLACE_ME_KEYCLOAK_ADDRESS }}/auth/realms/deploy-realm/protocol/openid-connect/certs
      forwardOriginalToken: true
    - issuer: {{ REPLACE_ME_KEYCLOAK_ADDRESS }}/auth/realms/master
      jwksUri: {{ REPLACE_ME_KEYCLOAK_ADDRESS }}/auth/realms/master/protocol/openid-connect/certs
      forwardOriginalToken: true
```

There is also a new `AuthorizationPolicy` defined for access to Keycloak. In the following content `REPLACE_ME_KEYCLOAK_ADDRESS` is the IP address or the URI of Keycloak .

```yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-only-master-jwt-for-admin
  namespace: istio-system
spec:
  action: ALLOW
  rules:
    - to:
        - operation:
            paths:
              - /auth/admin/*
              - /auth/realms/master/*
    - when:
      - key: request.auth.claims[iss]
        values:
          - {{ REPLACE_ME_KEYCLOAK_ADDRESS }}/auth/realms/master
  selector:
    matchLabels:
      app: istio-ingressgateway
```
