Instance configuration reference
Practical reference for the Craftifact instance configuration edited through the Control Plane.
What this configuration controls
In Craftifact, Effective configuration is the authoritative instance configuration for your instance. It controls repositories, access, storage references, robots, and retention behavior.
The normal workflow is:
- Edit the YAML in Effective configuration.
- Add or update secrets in Secrets if the YAML references
${VAR}placeholders. - Save and validate.
- Use Deploy Config to make the saved config the active runtime config.
${S3_*} values are injected automatically.
For most users, the right default is to keep that block unchanged.
Minimal example
This is the practical baseline the initial Control Plane flow seeds for a new Starter instance:
storage:
default: local-s3
backends:
local-s3:
type: s3
endpoint: ${S3_ENDPOINT}
bucket: ${S3_BUCKET}
credentials:
access_key_id: ${S3_ACCESS_KEY}
secret_access_key: ${S3_SECRET_KEY}
repositories:
- name: oci
type: oci
roles:
- name: admin
permissions:
- "*:*:*"
- name: developer
permissions:
- "oci:artifact:publish"
- "oci:artifact:read"
- "oci:artifact:redeploy"
- "oci:artifact:delete"
- "oci:composition:read"
- "oci:findings:read"
- name: viewer
permissions:
- "oci:artifact:read"
- "oci:composition:read"
- "oci:findings:read"
- "oci:license_policy:read"
- "oci:pull_gate:read"
role_assignments:
- role: admin
members:
- admin@example.com
The generated instance configuration replaces admin@example.com with the initial admin email you entered during creation.
On Pro and above, the seeded configuration also includes example retention_policies.
What you probably want to change next
- Add more repositories under
repositories. - Add proxy credentials via Secrets and reference them from
${VAR}placeholders. - Expand
roles,groups, androle_assignmentsfor your team structure. - Add
retention_policiesif you are on Pro or above. - Add
license_policiesandpull_policieswhen you want repository-level supply-chain gates. - Add
robot_accountsfor automation. - On Team, consider external S3-compatible storage only if you intentionally want to replace the seeded default.
Top-level keys
storage
Required. Defines the default storage backend and named backends.
Supported backend types are:
filesystems3azure_blobgoogle_cloud_storage
Hosted note:
- Below Team, validation only accepts the internal
${S3_ENDPOINT},${S3_BUCKET},${S3_ACCESS_KEY}, and${S3_SECRET_KEY}pattern for S3 storage. - External S3-compatible storage is a Team feature.
repositories
List of repository definitions.
Supported hosted repository types are:
maven,python,npm,ocigobetamaven_proxy,python_proxy,npm_proxy,oci_proxygo_proxymaven_group,python_group,npm_group,oci_groupgo_group
Common fields you will use most:
-
name -
type -
storage -
quota -
read_only -
redeploy -
upstream_url -
upstream_user -
upstream_password -
upstream_bearer_token -
upstream_tls_verify -
cache_ttlfor proxy repositories -
members -
retention -
license_policy -
pull_policy -
version_policyfor Maven
roles
Named permission bundles.
Permissions use the form <repository>:<domain>:<action>.
For the meaning of each supported domain/action pair, see Permissions and access model.
artifact:* grants artifact actions only.
Use <repository>:*:* for every domain in one repository, or "*:*:*" for all repo-scoped permissions.
Legacy permissions such as artifact:add, artifact:exec_elevated, artifact:manage_findings, artifact:manage_licenses, artifact:manage_policies, and sbom:* are no longer accepted. Use the domain-specific permissions above.
If you use * at the start of a permission string, wrap the full permission string in quotes in YAML, for example "*:*:*".
Otherwise, a leading * is not valid unquoted YAML scalar syntax.
groups
Named group definitions used by role assignments. A group must define exactly one of:
-
mail_domain -
members -
idp_group
role_assignments
Binds a role to one or both of:
-
members -
groups
robot_accounts
Declares automation identities. Useful fields are:
-
id -
description -
owners -
roles -
enabled -
token_policy
For the full workflow from declaration to token usage in the Robot accounts tab, see Create a robot account and use its token.
retention_policies
Available from Pro.
Defines named retention policies and optionally a default policy through retention_policies.default.
Named policies live under retention_policies.<name>.
Repositories reference them later through repositories[].retention.
Practical example with one general default policy and one selector-based OCI policy:
retention_policies:
default: default-policy
default-policy:
max_duration_since_published: 7d
max_duration_since_download: 7d
min_duration_since_published: 1d
keep_last: 3
oci-policy:
selectors:
name:
include: "^(craftifact|saas-controller)$"
version:
include: "^[0-9]+\\.[0-9]+\\.[0-9]+$"
exclude: "^latest$"
keep_last: 3
Available attributes per policy are:
max_duration_since_publishedDeletes artifacts once they are older than this duration since publication.max_duration_since_downloadDeletes artifacts that have not been downloaded for longer than this duration.min_duration_since_publishedEnforces a minimum lifetime since publication before deletion is allowed.keep_lastKeeps the lastNmatching artifacts regardless of the time-based rules.selectorsRestricts a policy to matching artifacts by name and/or version.
Under selectors, the available fields are:
selectors.name.includeselectors.name.excludeselectors.version.includeselectors.version.exclude
All four expect regex strings.
If selectors is set, at least one of those four fields must be configured.
Combination rules:
keep_lastcan be combined with all duration attributes.selectorscan additionally be combined withkeep_lastand the duration attributes.- If
selectorsis set,keep_lastmust be set explicitly. - If
selectorsis not set andkeep_lastis omitted, it defaults internally to0. retention_policies.defaultmust point to a defined named policy.- If
retention_policies.defaultis omitted, repositories without their own retention config are not automatically covered by a default policy.
Durations use the suffixes h, d, or y, for example 48h, 7d, or 1y.
license_policies
Defines named license policies and optionally a default policy through license_policies.default.
Named policies live under license_policies.<name>.
Repositories can use the default, reference another named policy, define an inline policy, disable policy enforcement, or delegate policy management to users with license_policy:configure.
License-policy helpers in Craftifact are informational guidance only, not legal advice. For background on identifiers and license texts, see SPDX and ChooseALicense.
Mixed-governance example:
license_policies:
default: company-default
company-default:
denied_spdx_ids:
- AGPL-3.0-only
- AGPL-3.0-or-later
unknown_license_action: unknown
permissive-only:
allowed_spdx_ids:
- Apache-2.0
- BSD-2-Clause
- BSD-3-Clause
- MIT
unknown_license_action: unknown
repositories:
- name: oci
type: oci
- name: research
type: python
license_policy:
policy: permissive-only
- name: delegated
type: npm
license_policy:
managed_by_users: true
- name: disabled
type: maven
license_policy: disabled
Policy rules:
allowed_spdx_idscreates an allowlist.denied_spdx_idscreates a denylist.- A policy must define exactly one of those two lists.
unknown_license_actionacceptsallow,deny, orunknown; default isunknown.license_policy: disableddisables policy evaluation for that repository, even when a default exists.managed_by_users: trueis exclusive with all concrete policy settings and named-policy references.
pull_policies
Defines named pull policies and optionally a default policy through pull_policies.default.
Named policies live under pull_policies.<name>.
Repositories can use the default, reference another named policy through pull_policy.policy, or define an inline pull_policy.
Pull policies apply to npm, Python, Maven, Go, and OCI pull paths. They can filter package metadata and hold or deny direct pulls depending on the enforcement mode and rule results. Group repositories cannot define their own pull policy.
Cooldown windows delay newly published packages until a configured minimum age has passed. Fast-track actions create a documented exception for a held package, so trusted releases can bypass the wait without disabling the policy for the repository.
Practical strict-gate example:
pull_policies:
default: strict-release-gate
strict-release-gate:
enforcement_mode: strict
cooldown:
minimum_release_age: 24h
unknown_release_time: hold
vulnerabilities:
max_severity: high
unknown_analysis: hold
licenses:
source: repository_license_policy
unknown_analysis: hold
content:
secrets: hold
misconfig: allow
malware: deny
hosted:
wait_for_required_scans: true
repositories:
- name: npm
type: npm_proxy
- name: experimental
type: python_proxy
pull_policy:
enforcement_mode: metadata_only
cooldown:
minimum_release_age: 12h
Policy rules:
enforcement_modeacceptsobserve,metadata_only, orstrict; default isobserve.metadata_onlyhides held content from package metadata while direct pulls can still proceed.strictcan hold or deny direct pulls and returns Craftifact policy decision headers for blocked requests.cooldown.minimum_release_ageaccepts duration values such as12hor7d.cooldown.unknown_release_timeacceptsallow,hold, oruse_first_seen; default isallow.vulnerabilities.max_severityacceptsunknown,low,medium,high, orcritical.vulnerabilities.unknown_analysis,licenses.unknown_analysis,content.secrets,content.misconfig, andcontent.malwareacceptallow,hold, ordeny; default isallow.licenses.source: repository_license_policyuses the repository license policy result as a pull-gate input.hosted.wait_for_required_scans: truemakes hosted artifacts wait for required analysis before release under a blocking mode.provenance.required: trueis reserved and currently rejected because provenance enforcement is not implemented yet.
scheduler
Optional advanced tuning for retention, quota checks, stalled-job retries, and OCI garbage collection cadence. Most users can leave this untouched.
Example:
scheduler:
retention:
interval: 6h
catchup: true
max_lateness: 30m
quota:
interval: 6h
catchup: true
max_lateness: 30m
vulnerability_rescan:
interval: 1d
stalled_job_retry:
enabled: true
max_attempts: 1
repositories:
- name: team-images
type: oci
oci:
gc:
interval: "*/15 * * * *"
max_lateness: 5m
Supported top-level sections are:
-
retention -
quota -
vulnerability_rescan -
stalled_job_retry
scheduler.retention
Available attributes are:
-
enabled -
interval -
catchup -
max_lateness
catchup and max_lateness work together:
- If a retention run starts later than
max_lateness, it is skipped whencatchup: false. - With
catchup: true, the same late job still runs.
scheduler.quota
Available attributes are:
-
enabled -
interval -
catchup -
max_lateness
Semantically this works like scheduler.retention, but for quota reconciliation instead of deletion rules.
scheduler.vulnerability_rescan
Available attributes are:
-
interval
Craftifact still starts the initial vulnerability scan after an uploaded or generated SBOM becomes ready. This setting only controls the periodic check for already stored reports that became stale because the vulnerability database, scanner version, scan state, or SBOM changed.
scheduler.stalled_job_retry
Available attributes are:
-
enabled -
max_attempts
This is not a periodic sweep like retention or quota.
The logic runs when a worker starts and retries jobs that the queue system considers stalled.
OCI garbage collection per repository
For oci and oci_proxy repositories, you can also fine-tune garbage collection per repository under repositories[].oci.gc.
Available attributes are:
-
interval -
max_lateness
Important:
- There is no
scheduler.enabled. Scheduler registration is always active. - There is also no
repositories[].oci.gc.enabled. For OCI repositories, GC is always active; you only tune cadence andmax_lateness. - Other periodic platform jobs such as Procrastinate cleanup or checksum retries are wired internally and cannot be configured through this YAML.
Duration values here use the suffixes s, m, h, d, and w.
Alternatively, you can provide a cron expression directly.
If you use durations instead of cron, keep them aligned to sensible minute, hour, day, or week boundaries in practice.
Environment placeholders and secrets
Validation only allows ${VAR} placeholders in specific places:
- storage backend credentials
repositories[].upstream_userrepositories[].upstream_passwordrepositories[].upstream_bearer_token
For your own secrets, add the key in the Secrets tab and reference it as ${MY_SECRET} in YAML.
The control plane renders it to the prefixed runtime environment automatically.
Do not keep credentials, passwords, or tokens there in plain text. Use Secrets plus ${...} references consistently.
Do not expect unrelated platform environment variables to resolve just because they exist somewhere in the infrastructure.
Where to go from here
- For repository lifecycle behavior after config changes, see Repository lifecycle.
- For import follow-up after generated cleanup snippets, see Import repositories from Nexus.
- For package-specific caveats, see Package format notes.