For the complete documentation index, see llms.txt. This page is also available as Markdown.

Authorization

How Lunar Hub identifies callers and decides which operations each credential may perform.

Most Lunar Hub calls require authentication. Installations use a shared service token, CI jobs use short-lived OIDC tokens from their Git platform, and people sign in through Git platform OAuth. A small set of sign-in setup calls requires no credential.

Caller
Credential
Authority

Installation

Hub service token in LUNAR_HUB_TOKEN

Every permission

CI job

OIDC token from its Git platform in LUNAR_HUB_TOKEN

Its repository and commit

Person

Git platform OAuth through lunar login

Their role on the target repository

Every installation has a service token. Depending on its configuration, CI jobs and people can also authenticate with their own identities.

Permissions

Every Hub operation is assigned a permission, such as components.read or secrets.write. The table shows the built-in defaults; run lunar hub permissions to inspect the effective rules.

Permission
Scope
Access
GitHub role
GitLab role
CI job

components.read

COMPONENT

READ

read

reporter

own repo; fleet-wide: cataloged repo or config repo

components.collect

COMPONENT

WRITE

write

developer

own commit

components.run

COMPONENT

WRITE

write

developer

own commit; fleet-wide: config repo, protected branch

bypasses.manage

COMPONENT

WRITE

maintain

maintainer

own commit

hub.read

LUNAR_CONFIG_REPO

READ

read

reporter

cataloged repo or config repo

hub.operate

LUNAR_CONFIG_REPO

WRITE

maintain

maintainer

no

hub.pull

LUNAR_CONFIG_REPO

WRITE

maintain

maintainer

config repo, protected branch

secrets.read

LUNAR_CONFIG_REPO

READ

maintain

maintainer

no

secrets.write

LUNAR_CONFIG_REPO

WRITE

maintain

maintainer

no

admin.read

LUNAR_CONFIG_REPO

READ

maintain

maintainer

no

sql.connect

LUNAR_CONFIG_REPO

READ

maintain

maintainer

no

The Hub evaluates each permission according to the caller:

  • Service token: always allowed.

  • CI job identity: Git platform roles do not apply. The CI job column restricts the call to the job's repository, commit, or configuration repository. For WRITE operations scoped to LUNAR_CONFIG_REPO, the job must run on the branch the configuration was pulled from, and that branch must be marked protected. It does not need to be the repository's default branch, or be named main.

  • Personal sign-in: the Hub checks the person's role on the repository selected by Scope. COMPONENT uses the target component's repository; LUNAR_CONFIG_REPO uses the configuration repository. Only a granted role counts: the read anyone has on a public repository does not, so a public configuration repository opens nothing to people outside it. Role requirements can be overridden under authorization, but cannot go below the READ or WRITE access floor.

Configuration repository administrators

Whoever can change lunar-config.yml already decides what the Hub enforces and knows, so the table's target checks do not bind them:

  • A person with maintain (GitHub) or Maintainer (GitLab) or above on the configuration repository holds every permission in the table, on every component, unless authorization raised that permission above maintain / Maintainer. A raise still binds on the configuration repository: secrets.read: { github_role: admin } requires admin there, which a Maintainer cannot merge past branch protection to undo. A bypass they create on a component they hold no role on records verified_role as their role on the configuration repository, suffixed with it — github:maintain@github.com/acme/lunar-config — so an audit can tell it apart from a role verified on the component.

  • The configuration repository's own CI job, running on the protected branch the configuration was pulled from, may make any call the CI job column opens to CI jobs, on any component or commit. A role raise does not apply: CI jobs have no git platform role. Calls marked no stay refused: a workflow on that branch is not the administrator, and any step in it holds the job's token.

The Hub checks this only after the ordinary rule refuses, so nothing that passes today changes, and a refusal reads exactly as before. internal calls and lunar hub pull are excluded: pulling the configuration from a different repository still requires hub.pull on both the current and the new repository. lunar hub permissions prints a note under its table when the connected Hub applies this.

Protect the branch the configuration is pulled from so that only reviewed changes reach it. On a Hub pulling github://acme/lunar-config@release, that is release, not the repository's default branch. Without that, anyone who can push to the branch administers Lunar.

components.read

Reads about a component: its status, Component JSON, catalog entry, and bypasses.

components.collect

Records collection data against a commit.

components.run

Runs collectors or catalogers.

bypasses.manage

Creates and revokes bypasses, from the CLI and from a /lunar bypass comment alike. The comment path checks the commenter's role on the pull or merge request's own repository against this permission's role, so an authorization override moves both surfaces at once; the configuration repository administrator rule below applies to the CLI only.

A CI job may create one only for a component in its own repository and only for its own commit, which it must name, so the next push retires it. Revoking is scoped to the job's repository, since it carries no commit and only removes authority. The configuration repository's own job is not held to either bound, though it must still name the commit. Fork pull-request jobs and GitHub pull_request_target jobs are refused, as for any other WRITE.

hub.read

Reads Hub-wide runtime data. It is also what admits a person to the dashboards when they sign in through the Hub: whoever holds it gets in, as a Grafana Viewer, and whoever loses it is signed out within 15 minutes. Raising its role under authorization raises both the dashboards and the read-only CLI calls together.

hub.operate

Changes Hub-wide runtime state.

hub.pull

Installs Lunar configuration.

secrets.read

Reads secret names and values.

secrets.write

Sets and deletes secrets.

admin.read

Reads operator-only Hub data.

sql.connect

Obtains a SQL API credential.

The three fixed permissions

These are not configurable:

  • public — no credential required

  • authenticated — any recognized credential

  • internal — service token only

When a call is refused

Code
What it means

Unauthenticated

Missing or invalid credential

PermissionDenied

Recognized caller without the required permission

Unavailable

Git platform verification failed temporarily

ResourceExhausted

Too many failed authentication attempts

FailedPrecondition

The operation needs Hub state or configuration that is unavailable; token exchange uses this when the session signing key is missing

Last updated