Skip to main content

Authz, Principals, and Tenants

In order to provide a secure platform for use at large enterprises, LittleHorse supports multi-tenancy natively. This is accomplished through two API Objects:

  • The Principal, which represents the identity of a client of LittleHorse (either a human or a machine).
  • The Tenant, which represents a logically isolated environment within LittleHorse.

Principals and Tenants reached General Availability in the 0.10.x release of LittleHorse.

Authz with Principals

In the 2020's, every company whether large or small must treat security as a top priority. This is especially true for systems like LittleHorse which can be used to orchestrate your most critical business processes. Therefore, when designing LittleHorse, we introduced the Principal concept to represent the Identity of a user (machine or human) of LittleHorse.

Design goals for Principals include:

  • The Principle of Least Privilege.
  • Fine-grained access control.
  • Reliance upon open standards.

A Principal is a first-class object in the LittleHorse API which can be adminstered through various rpc requests.

Authenticating a Caller

Every RPC call to the LittleHorse API is resolved to a Principal via authentication. The LittleHorse Server supports both OAuth and MTLS for authentication, configured on a per-listener basis.

The rules for authenticating a call are as follows:

  • If the listener uses MTLS:
    • The Principal ID is determined from the Common Name on the client's certificate.
    • Any requests that fail to present a valid certificate signed by a configured trusted authority will fail at the network level.
  • If the listener uses OAUTH:
    • For requests from a human client (eg. lhctl and the Dashboard), the Principal ID is determined by the User ID of the presented token.
    • For requests from a machine client (eg. a Task Worker), the Principal ID is determined by the Client ID of the presented token.
    • Requests that fail to present a valid token from the configured issuer fail with UNAUTHENTICATED.

If a Principal exists with a matching ID, the request is authorized according to that Principal's ACL's. If no Principal exists with the provided ID, then the request is authorized according to the anonymous Prncipal's ACL's.

The anonymous Principal

When a LittleHorse Cluster is first created, there exists one Principal out-of-the-box with the name anonymous. The anonymous Principal initially has full admin privileges over the entire LittleHorse cluster.

This is great for getting started in local development, and also for ease of use on private and trusted networks. However, LittleHorse allows you to fully secure your cluster by disabling the permissions of the anonymous Principal.

There are several motivations for this design:

  • Online Migrations to Secured Clusters: this design allows users to migrate to a secure cluster without downtime by adding a secured listener, adding Principals for each application, moving applications to the new listener, and disabling anonymous's permissions.
  • Developer Experience: this design allows LittleHorse to "just work" without understanding Principals or Tenants.
  • Fine-Grained Permissions: ACL's on the Principal resource allow fine-grained control over who can access what resource.

Authorizing Requests

Once a request has been authenticated and a Principal has been determined (either as the anonymous Principal or a custom user-created Principal), the LH Cluster checks the ACL's on the Principal against the required permissions for the request.

The ACL resources and actions over those resources are documented in our API Specification. Many requests are scoped to a Tenant; in those cases, the LH Cluster verifies that the calling Principal has the appropriate permissions either globally or within the specified Tenant.

If a calling Principal lacks permissions to perform the request, then the GRPC error PERMISSION_DENIED is returned.

Multi-Tenancy with Tenants

At large enterprises, there is sometimes a motivation to provide logically isolated environments within a single physical LittleHorse cluster. This can be achieved using a Tenant.

Every workflow-related resource (WfSpec, WfRun, TaskDef, TaskRun, NodeRun, ExternalEvent, etc) is scoped to within a Tenant. That means that within tenant foo and tenant bar, you can have two different WfSpec's titled my-workflow.

A Principal can have global_acls assigned to it, which allow the Principal to perform actions over any Tenant. Additionally, a Principal may have per_tenant_acls assigned to it, which allow the Principal perform actions over resources within only a specific and specified Tenant.

Clients can control which Tenant they are connected to by using the LHC_TENANT_ID configuration.