Skip to content

Authorization

Controlling and auditing who can do what to your software infrastructure is critical to the integrity of your business since in most cases, software controls all aspects of the business.

First level of defense: controlling direct access to live resources

Your core level of defense is the access control implemented on the live resources itself: Cloud account credentials, account separation, Cloud and Kubernetes IAM/RBAC, etc.

ConfigHub can never do more than what you permit via these access controls.

ConfigHub does not manage, access, or store your secret infrastructure credentials. Configuration reaches your infrastructure by being published and pulled by a GitOps operator running inside it, so the operator holds those credentials and ConfigHub never needs them. You can manage them however you are accustomed to doing.

Access control and Permissions within ConfigHub

ConfigHub allows you to establish another layer of authorization. In many cases, it can be less flexible or at least more cumbersome to provide the right balance between strict access control and efficient self-service using the live infrastructure access controls alone. ConfigHub enables you to delegate control based on your organization's needs.

ConfigHub includes a flexible but simple authorization model that is designed to meet the needs of all types of business operations. ConfigHub uses a medium level of granularity and customization so that granting common permissions is not excessively complicated.

Simplifications include:

  • Operations are classified into categories. For instance, Update, Patch, and Delete operations are all classified as the Edit category.
  • Permissions are cumulative. For example, the Use category also includes the operations contained within the View category, such as Get and List operations.
  • Most permissions are granted on a Space for everything in it rather than on every individual entity, though any entity can be given permissions of its own. (Discussed below in more detail.)
  • Where permissions are specified for a specific entity, they are represented within that entity directly, as opposed to using a separate API, which simplifies viewing and changing the permissions.
  • List operations and bulk operations are automatically filtered by what you are allowed to view.
  • Create operations have an independent permission, and the creator is granted permission to Manage the entities that they created. This enables organization members to use ConfigHub relatively freely without impacting the work of other organization members while not gaining access to privileged infrastructure without an explicit grant of permissions. (Permissions levels are discussed in more detail below.)
  • Use permissions (discussed below in more detail) facilitate delegation of authority by pre-establishing relationships, so that a person or a service account acting on those relationships does not need broad access of its own.

Permissions inheritance

Most permissions are controlled at the Organization level and the Space level. A permission granted on a Space with one of the Children categories described below applies to every entity in that Space.

Spaces are intended to both simplify permission management and also to help users discover entities that "belong" together. For example, imagine you have a platform team who is responsible for setting up the infrastructure on behalf of several app teams. The platform team uses a platform space to keep configuration that should not be accessible and/or is not relevant to app teams.

Every entity that can be created or changed also has a Permissions field of its own, other than Organizations and Users: Spaces, Components, Targets, Workers, Service Accounts, Units, Links, Triggers, Attributes, Invocations, Filters, Views, Tags, ChangeSets, ChangeOrders, ChangeWorkflows, Releases, and Attestations. An operation on an entity is allowed if the entity's own Permissions allow it or if its Space's Children permissions do, so a grant on one entity adds to what the Space grants and never takes anything away. A Unit's Revisions, Mutations, UnitEvents, and Resources have no Permissions of their own and follow their Unit's, and then its Space's.

It is recommended that you rely on Space-level permissions as much as possible by grouping entities within Spaces appropriately, and grant permissions on individual entities for the exceptions: letting another team view one Unit, or letting someone use one Target. Note that Triggers, which are used to maintain invariants and enforce policies on configuration data, are selected at the Space level as well.

The creator of an entity is granted Manage on it, and on a Space, Target, or Worker also ManageChildren. A clone keeps the Permissions of the entity it was copied from, and its creator is granted Manage in addition. To start clones without the source's Permissions, clear them in the patch the clones are created with, which leaves only the creator's Manage:

echo '{"Permissions": null}' | cub unit create --space payments-prod --where "Slug = 'web'" --dest-space payments-staging --from-stdin

An Attestation is never updated, so its Permissions can only be set when it is recorded.

Lists and bulk operations leave out the entities you are not allowed to view, and a lookup by name reports an entity you cannot view as not found. The cub CLI looks up the Space named by --space, so to work with an entity in a Space from the CLI you also need View on the Space itself. View on a Space shows the Space but none of the entities in it:

cub space update --permission View:user@example.com payments-prod
cub unit update --space payments-prod --patch --permission View:user@example.com web

Organization Roles

Every member of an Organization has an Organization role, which grants permissions on all Spaces in that Organization. A user's role comes from the identity provider they sign in with. A sign-in that carries no recognized role is refused.

The roles currently supported are:

  • admin: Superuser. Can perform any and all actions to all entities within ConfigHub, including adding and removing Organization Members and changing Organization metadata.
  • manager: Can perform most actions to most entities within ConfigHub, except adding and removing Organization Members and changing Organization metadata.
  • editor: Can change mutable fields other than Permissions and DeleteGates of all Spaces. Can delete Spaces not protected by DeleteGates. Includes user and creator permissions.
  • user: Can use the entities in all Spaces: reference them from other entities and copy them. Copying into a Space also requires permission to create entities in it, which user does not grant. Includes viewer permissions.
  • viewer: Can get and list all Spaces.
  • creator: Can create Spaces.
  • none: No default permissions at the Organization level.

Note that creator does not provide viewer, editor, or manager permissions at the Organization level. It means that the Organization Member can create and use their own Spaces, but not access other Spaces without explicitly being granted permission.

Permissions settings

The Permissions field is a map of operation category to Subjects, which is a set of users and a set of Groups (represented as maps of UserIDs and GroupIDs to facilitate lookups and patching). A grant to a Group applies to all of its members, and a user is allowed an operation if it is granted to them or to any Group they belong to. Changing Permissions requires Manage permission. The --permission flag of cub create and update commands adds a subject to a category and, prefixed with -, removes one. A subject is a user, as Category:user@example.com or Category:<user ID>; a Group you belong to, as Category:group:<slug or ID>; or a service account, as Category:serviceaccount:<name>.

The general categories are:

  • Manage: Can change Permissions, DeleteGates, and DestroyGates (in Units). Includes Edit permissions.
  • Edit: Can change other non-readonly, non-immutable fields and delete the entity if DeleteGates is empty. Includes Use and Create permissions.
  • Use: Can copy the entity, reference it in other entities, and reference it in non-CRUDL operations. Includes View permissions.
  • View: Can read the entity, such as using Get or List APIs, and invoke readonly functions (on Units and Revisions). The view permission allows an actor to see all data for an entity without changing anything. Most organizations should be liberal with granting read permissions because it allows teams to discover and learn on their own.
  • Create: Can create new entities. (Not directly usable. See CreateChildren, below.)
  • Impersonate: Can register and delete the keys of a service account, with which whoever holds them authenticates as it, and issue and revoke its long-lived tokens. It applies only to service accounts, includes View, and is not included in Manage; only someone who has it can grant it.

One case where permissions are not cumulative is to distinguish permissions on an entity from permissions to access children of that entity. These are granted on Spaces, Targets, and Workers, and are most important for Spaces. On a Target, ViewChildren allows viewing the Releases published for the Target, the Spaces that release to it, and the Units attached to it.

  • ManageChildren: Can change Permissions, DeleteGates, and DestroyGates (in Units) of child entities. Includes EditChildren permissions.
  • EditChildren: Can change other non-readonly, non-immutable fields and delete child entities if DeleteGates is empty. Includes UseChildren and CreateChildren permissions.
  • UseChildren: Can copy child entities, reference them in other entities, and reference them in non-CRUDL operations. Includes ViewChildren permissions.
  • ViewChildren: Can read child entities, such as using Get or List APIs, and invoke readonly functions (on Units and Revisions).
  • CreateChildren: Can create new child entities. This does not grant ViewChildren, EditChildren, or ManageChildren permissions, so a user with only CreateChildren on a Space can view and change only the entities they create in it, on which they are granted Manage.

There are some Space permissions specific to Unit operations.

  • ApproveChildren: Can record Attestations, such as approvals, of the Space's Units. Note that recording an approval does not imply that a ChangeWorkflow's approval requirements will be satisfied, since those can name eligible users and exclude a change's authors.
  • TargetEditChildren: Can invoke actions, such as Apply and Destroy, that modify the Targets attached to the Unit(s). Includes View permission for those Units.
  • TargetViewChildren: Can invoke actions, such as Refresh and Import, that read from the Targets attached to the Unit(s) and update the Units accordingly. Includes Edit permission for those Units.

ManageChildren includes all of those permissions.

Authorization delegation via Use permissions

ConfigHub's permissions model enables authorization delegation as follows:

  1. An Organization member given CreateChildren permission in some Space(s) can create Targets. An automation that needs an identity of its own gets a service account, which any member can create.
  2. An Organization member given CreateChildren permission, likely in another Space, can create Units.
  3. An Organization member given Use permission (potentially via UseChildren) to the Targets and Edit permission (via EditChildren) to the Units can update the Units' TargetIDs to attach the desired Targets to the desired Units. This creates a durable association between them.
  4. An Organization member given TargetEditChildren and/or TargetViewChildren permission on the Space containing the Units can invoke Apply, Destroy, Refresh, and/or Import actions on the Units with attached Targets.
  5. A GitOps operator's identity — a service account presenting a long-lived token — with ViewChildren permission on a Target can pull the Releases published for that Target from the OCI endpoint, without any permission on the Space they came from.

Once associations between the Targets and Units have been established, they represent authorization by themselves that can be utilized by Organization members without permission to establish those assocations.

For example, Jane is one of a few people who manages the clusters and she is responsible for setting up Targets for teams who need to deploy to certain accounts -- step (1) above. After she create a Target, she grants Use permission to the operations team who needs to deploy to this particular part of the infrastructure. This team can now associate Units with the Target but they cannot otherwise change the Target.

Let's say John is on that team. If John has Use permission on Target T and Edit permission on Unit U, then he can attach Target T to Unit U by setting the TargetID field on the Unit -- step (3) above. Once this association have been created, it represents an authorization for Unit U to be applied to Target T.

So if Jessie has TargetEditChildren permission on the Space containing Unit U, then an Apply will succeed regardless of what permissions Jessie has on Target T -- step (4) above. Similarly, if a CI bot user has TargetEditChildren permission on the Space containing Unit U, it can also perform applies regardless of other permissions.

The choice of this model stems from the nature of a business. A business is a system of business processes that transcend the humans involved with the business. The systems keep running as people join and leave a company. People are responsible for setting up new systems and change or retire existing systems. Once this is done, the systems do the work and people can quit or transfer to other positions while the system keeps running.

Responsibility for the system is based on the org chart. A system should not be owned by a person. It should be owned by a team or group that maps to an organizational unit in the org chart. This allows people to come and go without causing ownership problems. Groups, which mirror the groups in your identity provider, let you grant permissions to such a team directly.