Skip to main content
policy.md4.5 KB
View on GitHub

Plugin Policy Reference

Rules with on: plugin run in the shared policy engine (CEL or restricted Starlark). They load from policy.d/ next to the selected atmos.yaml, or from ATMOS_POLICY_DIR. A denial or evaluation error blocks the operation, and no rule can weaken plugins.policy signature or trusted-publisher checks. Protect the policy directory, the Atmos binary and environment, and the lock file independently of candidate changes.

Phases

PhaseEvidenceUse
sourceregistry, repository, normalized source, operation, origin, development flag, path, profilesReject a destination or import origin before registry access or cached reuse
packagesource fields plus the inspected manifest and release digestReject a package before installation, activation, testing, publication, or signing

Name restrictions select phase == 'package'. Registry restrictions apply to both phases and must not depend on package metadata. Registry operations have no inspected package and use the source phase.

Operations

OperationGuarded action
installInstall a release or restore a declared package
activateLoad a plugin for use, including a cached package or a path package
testatmos plugin test on a local, unsigned directory
searchCheck configured discovery sources, including cached results
publish, signPublish or sign a release
registry.read, registry.write, registry.delete, registry.configure, registry.loginCatalog and registry operations

atmos plugin build compiles local source and runs no plugin code, so it is not an operation.

Input fields

All fields are always present; unknown strings are empty and unknown lists are empty.

FieldTypeNotes
operation, phasestringSee above
originstringregistry, cache, development, layout
sourcestringoci://registry/repository without tag or digest; registry login uses oci://registry; empty for local builds
registrystringAuthority including explicit port; empty for local builds
repositorystringPath within the registry
name, version, digest, runtimestringInspected package; empty in the source phase
capabilitieslist of stringFor example auth.identity, auth.provider, command; empty in the source phase
developmentboolLocal development package or conformance testing
pathstringProject-relative clean slash path (no ..) for origin: development inside the project; absolute outside; empty for other origins; symlinks resolved
profileslist of stringActive profile names as typed, deduplicated, in activation order; empty when none

source is not an authenticated publisher identity: an offline layout can claim any repository. Pair registry and package rules with trusted_publishers.

Recipes

Approved registries and packages (denies local builds and layouts):

approved-registries:
on: plugin
action: deny
reason: Plugins and catalogs must use the company registry
with: {allowed_registries: [registry.example.com]}
rule: "input.origin in ['development', 'layout'] || !(input.registry in params.allowed_registries)"
approved-packages:
on: plugin
action: deny
reason: Only approved plugin packages may be installed or activated
with: {allowed_plugins: [acme/oidc, acme/platform]}
rule: "input.phase == 'package' && !(input.name in params.allowed_plugins)"

Registries rule that permits local builds but not offline layouts, and a localhost registry:

with: {allowed_registries: [registry.example.com, "localhost:5001"]}
rule: "input.origin == 'layout' || (input.origin != 'development' && !(input.registry in params.allowed_registries))"

Local builds only below approved roots (a relative root never matches an absolute path outside the project):

with: {dev_roots: [plugins/]}
rule: "input.origin == 'development' && !params.dev_roots.exists(r, input.path.startsWith(r))"

Development allowed for plugin test only:

rule: "input.origin == 'development' && input.operation != 'test'"

Organization convention on profile names (advisory; limited to activate because plugin test has no profile):

rule: >-
input.origin == 'development' && input.operation == 'activate' &&
!input.profiles.exists(p, p.startsWith('local-'))

Starlark variants return a strict boolean from ctx.input[...], for example return ctx.input["origin"] == "development" and ctx.input["operation"] != "test".