# Users

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/management/core/user>.

## Types

There are currently two types of *Users* in Octelium:

1. `HUMAN` *Users*, utilized by humans. `HUMAN` *Users* primarily authenticate themselves via the web portal of the [*Auth Server*](https://octelium.com/docs/octelium/latest/reference/components.md#auth-server) using *IdentityProviders* such as GitHub OAuth2 or any identity provider that supports OpenID Connect or SAML 2.0 (read more about *IdentityProviders* [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md)).

Here is an example of a `HUMAN` *User*:

```yaml
kind: User
metadata:
  name: alice
spec:
  # !mark
  type: HUMAN
```

2. `WORKLOAD` *Users*, used by non-human entities such as containers, servers, programmable environments, etc.... By default, `WORKLOAD` *Users* have 3 options to authenticate themselves to the *Cluster*:
   1. Authentication token [*Credentials*](https://octelium.com/docs/octelium/latest/reference/resources.md#credential)
   2. OpenID Connect-based assertion by an external identity provider (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md#oidc-assertion)).
   3. OAuth2 client credentials *Credentials* and used by applications written in any programming language to authenticate in a clientless way via the standard OAuth2 client credentials flow (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential.md#oauth2-client-credentials)).

Here is an example of a `WORKLOAD` *User*:

```yaml
kind: User
metadata:
  name: k8s-1
spec:
  # !mark
  type: WORKLOAD
```

## Groups

A *User* may belong to one or more *Groups* (more details on *Groups* can be found [here](https://octelium.com/docs/octelium/latest/management/core/group.md)). Here is an example:

```yaml
kind: User
metadata:
  name: usr-1
spec:
  type: WORKLOAD
  # !mark
  groups: ["group-1", "group-2"]
```

## Email

You can set a primary email address for `HUMAN` *Users* to be used as the main identifier with OpenID Connect and SAML 2.0-based *IdentityProviders* (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md#web-identity-providers)). Here is an example:

```yaml
kind: User
metadata:
  name: alice
spec:
  type: HUMAN
  # !mark
  email: alice@example.com
```

## Authentication

In addition to using the primary email as a main identifier as shown above, A *User* can have one or more explicit identities that can be used to authenticate the *User* for a certain *IdentityProvider* (read more about *IdentityProviders* [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md)) such as [OpenID Connect](https://openid.net/connect/), SAML 2.0, GitHub OAuth 2 for `HUMAN` *Users*. In practice, identities are more useful for `WORKLOAD` *Users* when used with OpenID Connect assertions (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md#oidc-assertion)).

Here is an example of a *User* that has multiple identities that can be used
for authentication:

```yaml
kind: User
metadata:
  name: usr-1
spec:
  type: HUMAN
  authentication:
    identities:
    - identityProvider: github
      identifier: linus
    - identityProvider: okta-oidc
      identifier: linus@example.com
    - identityProvider: saml-idp1
      identifier: linus@example.com
```

The `identityProvider` field is the *IdentityProvider* name. The `identifier` is the value used for verification upon obtaining the *User*'s information from the *IdentityProvider* during the authentication flow. Such information could be the OIDC identity token in the case of an OpenID Connect *IdentityProvider* or a SAML assertion in the case of SAML 2.0 *IdentityProviders*. It's important to note that the default value of the identifier depends on the *IdentityProvider* type:

- For GitHub OAuth2-based *IdentityProviders*, the identifier is the username (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md#github-oauth2)).
- For OpenID Connect *IdentityProviders*, the identifier, by default, is the value of the `email` claim in the identity token (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md#openid-connect)).
- For SAML 2.0 *IdentityProviders*, the identifier by default is the value of the `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` attribute. The *Cluster* administrators can override the default identifier claim in the case of OIDC or identifier attribute in the case of SAML 2.0 (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers.md#saml-20)).

> **Note:**
>
> Note that Octelium prioritizes authentication against an explicit identity over the primary email. If it doesn't find a match in the `identities` list or if the list is empty, it will use the email as the fallback identifier.

## Session

*Users* can interact with the *Cluster* and access its *Services* as long as their *Sessions* are valid.
You can set a per-*User* *Session* duration value, after which the *Session* is deemed expired and is automatically deleted by the *Cluster* (namely by [*Nocturne*](https://octelium.com/docs/octelium/latest/reference/components.md#nocturne)). These per-*User* *Session* options override the *Cluster*-wide values set in the *ClusterConfig* (read more [here](https://octelium.com/docs/octelium/latest/management/core/cluster-config.md#session-durations)). You can also set the default state of the *User*'s *Sessions*, namely `ACTIVE`, `REJECTED` or `PENDING` (read more [here](https://octelium.com/docs/octelium/latest/management/core/session.md#state)). Here is an example:

```yaml
kind: User
metadata:
  name: usr-1
spec:
  type: HUMAN
  # !mark(1:10)
  session:
    clientDuration:
      days: 1
    clientlessDuration:
      hours: 10
    maxPerUser: 100
    accessTokenDuration:
      hours: 4
    refreshTokenDuration:
      days: 1
    defaultState: ACTIVE
```

## Disabling Users

You can disable/deactivate a *User* and immediately revoke their ability to interact with the *Cluster* or access its *Services*. Here is an example:

```yaml
kind: User
metadata:
  name: usr-1
spec:
  type: HUMAN
  # !mark
  isDisabled: true
```

To re-activate the *User*, you simply set the `isDisabled` field back to `false`.

## Policies

*Policies* (read more about *Policies* and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy.md)) can be created and/or attached to *User* where they serve as principal-based policies for a specific *User*. Here is an example:

```yaml
kind: User
metadata:
  name: john
spec:
  type: HUMAN
  authorization:
    policies: ["policy-1", "policy-2"]
    inlinePolicies:
      - spec:
          rules:
            - effect: DENY
              condition:
                match: 'ctx.service.status.namespaceRef.name == "production"'
```

## Listing Users

You can list the *Cluster*'s *Users* (read more about listing resources [here](https://octelium.com/docs/octelium/latest/management/core/overview.md#listing-resources)) as follows:

```bash
octeliumctl get user
# Or simply
octeliumctl get usr

# Show a certain User
octeliumctl get usr <NAME>
```

## Privileged Users

Octelium, by design, has no inherent concept of an "admin" or "superuser" *User* by default. All access to any *Service* including to the *Cluster* *API Servers* (note that the *API Servers* are deployed as typical Octelium *Services*) has to be explicitly allowed by a *Policy* (read more about access control [here](https://octelium.com/docs/octelium/latest/management/core/policy.md)). It should be noted that Octelium's API Server itself is exposed to *Users* as an ordinary gRPC *Service*.

The closest to an "administrator" privilege that can be granted to a certain *User* is to attach a *Policy* or add an *InlinePolicy* that allows all access for that *User*. For example, you can achieve that via an *InlinePolicy* as follows:

```yaml
kind: User
metadata:
  name: john
spec:
  type: HUMAN
  authorization:
    inlinePolicies:
      - spec:
          rules:
            - effect: ALLOW
              condition:
                matchAny: true
```

Alternatively, you can attach the `allow-all` *Policy* that's installed automatically upon the *Cluster* installation as follows:

```yaml
kind: User
metadata:
  name: john
spec:
  type: HUMAN
  authorization:
    policies: ["allow-all"]
```

It's very important to understand that `ALLOW` rules are overridden by `DENY` rules of the same or higher priorities. Therefore, the above *Policy*/*InlinePolicy* rule only guarantees full access as long as there are no `DENY` rules overriding it in any of the one or more *Policies* that are relevant for a certain request (i.e. any rules of any of the *Policies* and *InlinePolicies* attached to the *Session*,the *User*,  the *User*'s *Groups*, *Device* if available, as well as the *Service* and its *Namespace*). You can read in detail about *Policies* and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy.md).

## Attributes

You can extend the information of a *User* by providing it additional, whether manually or dynamically, via the APIs (read more [here](https://octelium.com/docs/octelium/latest/management/guide/sdk.md)) from external sources (e.g. IAM platforms, SIEM tools, threat intelligence tools, incident alerting and on-call management tools, etc...). Such additional information can be especially useful for extending access control and making it as fine-grained and dynamic as you wish (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy.md#extending-access-control)). Here is an example:

```yaml
kind: User
metadata:
  name: john
spec:
  type: HUMAN
  email: john@example.com
  attrs:
    pagerDuty:
      onCall: true
    azureAD:
      isAdmin: true
    isFriend: true
    age: 27
    anotherTool:
      key1: val1
      key2: 100
      key3: true
      key4:
        subKey1: subVal1
```

> **Note:**
>
> The `attrs` field is also available for *Groups*, *Services* and *Namespaces*.

## API Reference

[User JSON Schema (Octelium core/v1, latest documentation)](https://octelium.com/schemas/octelium/latest/core.v1.User.schema.json)
