Skip to main content
Version: Next 🚧

Authorization

Since version 1.11.0 Epinio is shipped with a new authorization layer with two default roles: admin and user. Roles can be "namescoped", and they can be also customized with different permissions.

A user with the admin role will have the permission to perform any operation. A standard user has read access across resources and can create namespaces (automatically gaining admin permission on namespaces they create). As of 1.14.1 the default user role also grants builder-image management; see the role definition below.

By default, after the installation two users are available: admin and epinio, both with the password password. The operator can control the creation of those users through the api.users key in values.yaml. In a production setup, the default api.users value needs to be overridden.

Switch user​

To switch users you need to set the user and pass keys of the Epinio settings file, located at ~/.config/epinio/settings.yaml. The password has to be base64 encoded. Below, cGFzc3dvcmQ= is the base64 encoded version of password.

You can also login again with the epinio login [URL] command.

api: https://epinio.mydomain.com
appchart: ""
certs: |
-----BEGIN CERTIFICATE-----
MIICUTCCAfigAwIBAgIQXJq3y/ouo90Db7BWy34gbDAKBggqhkjOPQQDAjAUMRIw
****************************************************************
****************************************************************
****************************************************************
qCPZOyTsHKnjmj7zxg57+Kq2KLFT
-----END CERTIFICATE-----
colors: true
namespace: workspace
pass: cGFzc3dvcmQ=
user: epinio
wss: wss://epinio.mydomain.com

List the Epinio users​

An Epinio user is a BasicAuth Kubernetes Secret, with the epinio.io/api-user-credentials reserved label.

To list the available users you can get the secrets from your cluster with kubectl, filtering them with the proper labels:

# list all the users
kubectl get secrets -n epinio -l 'epinio.io/api-user-credentials'
NAME TYPE DATA AGE
default-epinio-user BasicAuth 3 5m10s
admin-epinio-user BasicAuth 2 5m10s

Add a new user​

Since a user is simply a Kubernetes Secret you can create a new user with a kubectl apply:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
type: BasicAuth
metadata:
labels:
epinio.io/api-user-credentials: "true"
epinio.io/roles: "admin"
name: my-epinio-user
namespace: epinio
stringData:
username: myuser
password: "\$2a\$10\$6bCi5NMstMK781In7JGiL.B44pgoplUb330FQvm6mVXMppbXBPiXS"
EOF

Roles​

An Epinio role is a Kubernetes ConfigMap, with the epinio.io/role reserved label.

The following yaml shows you the default user role:

apiVersion: v1
kind: ConfigMap
metadata:
labels:
epinio.io/role: "true"
name: "epinio-user-role"
namespace: {{ $.Release.Namespace }}
data:
id: user
name: "Epinio User Role"
default: "true"
actions: |
namespace_write
app_read
configuration_read
service_read
gitconfig_read
export_registries_read
builderimage_read
builderimage_write

Fields​

KeyDescription
idThe ID of the Role
nameA friendly name for the Role
default(optional) if set to true the role will be the one selected as default if no other roles were assigned to the user
actionsThe actions the roles can perform

Actions​

Each Role can perform some actions defined in the actions field (newline separated). These actions are hardcoded in Epinio, and some of them depend on other actions. Enabling an action with a dependency will automatically enable the dependency as well.

Namespace​

These actions enable operations on Namespace commands and resources.

Action IDDescription
namespace_readRead permissions (list, show)
namespace_writeWrite permissions (create, delete)
Depends on: namespace_read
namespaceAll the above
Depends on: namespace_read, namespace_write

App​

These actions enable operations on App commands and resources, plus application environment variables. Read access to AppCharts comes bundled here (app_read depends on chart_read); AppChart management has its own actions, see Chart below.

Action IDDescription
app_readRead permissions (app list and show, env list and show)
app_logsRead application logs
app_restartRestart permission (without write permissions)
Depends on: app_read
app_createCreate and upload/import applications
Depends on: app_read, app_logs
app_updateGeneric application update (patch) covering routes, chart values, instances and settings
app_scaleScale applications by changing the desired number of instances (implemented via the AppUpdate endpoint)
app_update_envUpdate application environment variables (set and unset)
app_update_configsManage application configuration bindings (create and delete)
app_update_routesUpdate application routes/domains (implemented via the AppUpdate endpoint)
app_update_settingsUpdate application settings (chart values) stored on the App resource (implemented via the AppUpdate endpoint)
app_update_chartUpdate application chart selection and values (implemented via the AppUpdate endpoint)
app_stageStage an application
Depends on: app_read, app_logs
app_deployDeploy an application
Depends on: app_read, app_logs
app_exportExport an application image and metadata
app_deleteDelete applications
app_writeBackward-compatible umbrella for app create/update/delete/export/stage/deploy and all application update operations (including scale, routes, settings, chart and env/config updates)
app_execPerform an exec into a running application
app_portforwardOpen a tunnel with the port-forward command
appAll app permissions (including granular app actions, logs, exec and port-forward)

Chart​

These actions enable operations on AppChart commands and resources (epinio app chart). AppCharts are cluster-scoped, so these actions are only effective when granted by a global (non-namespaced) role.

Action IDDescription
chart_readRead permissions (list, show, match). Granted automatically to any role with app_read.
chart_writeWrite permissions (create, update, delete)
Depends on: chart_read
chartAll the above
Depends on: chart_read, chart_write

Builder Image​

These actions enable operations on BuilderImage commands and resources. BuilderImages are cluster-scoped, so these actions are only effective when granted by a global (non-namespaced) role.

Action IDDescription
builderimage_readRead permissions (list, show, match)
builderimage_writeWrite permissions (create, update, delete)
Depends on: builderimage_read
builderimageAll the above
Depends on: builderimage_read, builderimage_write

Configuration​

These actions enable operations on Configuration commands and resources. Be aware that to bind a configuration you still need the app_write permission as well.

Action IDDescription
configuration_readRead permissions (list, show)
configuration_writeWrite permissions (create, delete)
Depends on: configuration_read
configurationAll the above
Depends on: configuration_read, configuration_write

Service​

These actions enable operations on Service commands and resources, covering both service instances (namespaced) and catalog services (cluster-scoped).

Action IDDescription
service_readRead permissions (list, show) for service instances and catalog services
service_writeWrite permissions for service instances (create, update, delete, bind, unbind) and catalog services (create, update, delete)
Depends on: service_read
service_portforwardOpen a tunnel with the port-forward command
serviceAll the above
Depends on: service_read, service_write, service_portforward

Gitconfig​

These actions enable operations on Gitconfig commands and resources.

Action IDDescription
gitconfig_readRead permissions (list, show)
gitconfig_writeWrite permissions (create, delete)
Depends on: gitconfig_read
gitconfigAll the above
Depends on: gitconfig_read, gitconfig_write

Export Registries​

This action enable operations on Export Registries commands and resources. Only read operations are available.

Action IDDescription
export_registries_readRead permissions

Resource scope: cluster-scoped vs namespaced​

Epinio resources fall into two scopes, and the scope decides which of a user's roles can grant an action:

  • Namespaced resources (applications, configurations, service instances, and deleting an existing namespace) live inside a namespace. Actions on them are evaluated against the roles the user holds for that namespace, whether a namespace-scoped role such as admin:workspace or a global role.
  • Cluster-scoped resources (app charts, builder images, git configs, catalog services, and creating a namespace) do not live in a namespace. Actions on them are evaluated against the user's global (non-namespaced) roles only.

The practical consequence: a user who is admin of a single namespace (for example admin:workspace) can fully manage applications and delete that namespace, but cannot create an app chart, builder image, git config, catalog service, or a new namespace unless a global role grants it. The default user role is global, so everything it carries (including namespace_write and builderimage_write) applies cluster-wide.

Built-in Role Examples​

The following roles are shipped as ConfigMaps and can be assigned directly to users:

Role IDIntended scope
view_onlyRead-only access across all resource types (applications, builder images, configurations, services, git configs, export registries)
application_developerApplication create/update (no delete) and runtime, plus builder-image, configuration and service write. No app-chart write
application_managerFull application CRUD and runtime operations, plus builder-image, configuration and service write. No app-chart write
system_managerNo-delete role: application create/update/runtime, plus builder-image, app-chart, configuration and service write

Assign Roles to User​

The epinio.io/roles annotation is used to declare the list of the assigned roles. It's a comma separated string with the ID of the roles.

apiVersion: v1
kind: Secret
type: BasicAuth
metadata:
labels:
epinio.io/api-user-credentials: "true" # indicates this secret represents a user
annotations:
epinio.io/roles: "user,admin" # comma-separated list of roles
name: my-epinio-user
namespace: epinio
stringData:
username: myuser
password: "$2a$10$6bCi5NMstMK781In7JGiL.B44pgoplUb330FQvm6mVXMppbXBPiXS" # password hashed with the Bcrypt algorithm

Define Role Access to a Namespace​

Users may be granted access to a particular namespace via two mechanisms:

  1. Role Annotations with Scoping Delimiter : (recommended)

    • The roles assigned via the epinio.io/roles annotation on a user object may be namespace-scoped via the : delimiter.

      • Format: roleName:namespace
    • For example, a user may be granted administrator privileges to a specific namespace while maintaining non-admin access elsewhere:

      • Specifically, note the admin:some-namespace annotation item

        apiVersion: v1
        kind: Secret
        type: BasicAuth
        metadata:
        labels:
        epinio.io/api-user-credentials: "true"
        annotations:
        epinio.io/roles: "user,admin:some-namespace"
        name: my-epinio-user
        namespace: epinio
        stringData:
        username: myuser
        password: "some-hashed-password"
    • We recommend this approach as it aligns with the automated flow through OIDC authentication, expanded upon below.

  2. Namespaces Array on User Object

    • Namespaces can be assigned to a user via an additional namespaces key in the user Secret's data

    • These namespaces are represented as an array separated by newlines.

      apiVersion: v1
      kind: Secret
      type: BasicAuth
      metadata:
      labels:
      epinio.io/api-user-credentials: "true"
      epinio.io/roles: "user,admin"
      name: my-epinio-user
      namespace: epinio
      stringData:
      username: myuser
      password: "some-hashed-password"
      namespaces: |
      workspace
      workspace2

Additionally, this concept may be automated as part of OIDC authentication via Epinio's reference to a rolesMapping key within the dex-config secret data. Please refer to our documentation on OIDC Authentication for further explanation. Note specifically that the roles array within the rolesMapping secret value can include the same : delimiter described above.