Skip to main content

Source and Filesystem Policies

Source policies are opt-in on: source rules. Without configured restrictions, normal source behavior is preserved. Rules run before imports (including cached imports), downloads, YAML includes, and guarded template file or datasource operations. They use the same CEL/Starlark evaluators and pinned policy bundle as command admission.

Restrict transports and domains​

policy.d/sources.yaml
apiVersion: atmos/v1
kind: Policy
metadata:
name: sources
spec:
policies:
trusted-hosts:
on: source
action: deny
rule: >-
input.remote &&
(input.scheme != 'https' || !(input.host in ['github.com', 'raw.githubusercontent.com']))

The collector normalizes forced go-getter transports, supported Git shorthand, SCP-style URLs, host casing, and trailing dots. Policies see the effective transport scheme and hostname; credentials, query parameters, and request headers are omitted. HTTP redirect destinations are checked before being contacted. Protect the runner's transport configuration, credentials, and policy files.

FieldMeaning
operationimport, download, include, template.file, template.datasource, or template.dns
schemeEffective transport, such as https, ssh, file, or dns
hostNormalized hostname, without credentials or port
pathURI path, or an absolute local path with symlinks resolved when possible
remoteWhether the destination is outside the local filesystem
path_resolvedWhether the local path was successfully resolved through symlinks
provenancelocal, remote, or unknown origin of the calling configuration
source_fileAvailable caller attribution, with URI credentials and queries removed
within_allowed_rootsWhether the canonical local path is inside the rule's allowed_roots; computed only for rules with a nonempty allowed_roots list, and false for unresolved paths

Confine includes and template file reads​

policy.d/files.yaml
apiVersion: atmos/v1
kind: Policy
metadata:
name: files
spec:
policies:
confine:
on: source
allowed_roots: [../stacks, ../shared]
action: deny
rule: >-
input.operation in ['include', 'template.file', 'template.datasource'] &&
input.scheme == 'file' && !input.within_allowed_roots

allowed_roots is permitted only on source rules. Relative roots are anchored to the policy file's directory, not base_path or an imported configuration. Roots must be existing directories. Both roots and accessed paths are canonicalized. The rule receives input.within_allowed_roots, computed with path-segment boundaries, so sibling prefixes, parent traversal, and symlink escapes do not count as contained. An unresolved path is outside the roots. The predicate decides which operations to restrict. This is a configuration access gate, not an operating-system sandbox for arbitrary external programs.

Supported guarded transports​

Source-governed downloads check each go-getter destination and HTTP request. Archive extraction uses go-getter's symlink protection. Git HTTP redirects are disabled; recursive Git submodules and Mercurial downloads fail closed because their nested transport destinations are not collected.

Source-governed template datasources support local files, environment sources, and HTTP(S), including alias resolution and subpath handling. HTTP(S) responses are bounded to 16 MiB and five seconds; JSON, YAML, CSV, TOML, and text are supported. Other datasource schemes and the AWS/GCP template namespaces report unavailable guarded collection rather than bypassing source rules. Implicit EJSON key-file reads also fail closed; ordinary JSON remains supported. These limits apply when source policies are configured. YAML store and secret functions remain governed by function admission; source policies do not intercept arbitrary SDK calls or external tools.