Configuration¶
oci-nuke reads a single YAML file. Validate it before the first run — config validate
issues zero OCI API calls, so it is safe to run against anything:
oci-nuke config validate --config config.yaml
config.example.yaml in the repository is a commented starting point; this page is the
reference.
The three required keys are the safety model¶
Two of the three required keys exist only to stop a run going somewhere it was not meant to, and neither can be omitted.
tenancy-id¶
Before listing a single resource, oci-nuke calls GetTenancy and compares the answer against
this value. A mismatch exits non-zero immediately. This is what stops a config written for one
tenancy from ever running against another — the credentials do not get a say.
compartment-blocklist¶
Compartments that must never be touched. Matching is always by OCID and never by display name: compartment names are unique only within their parent, so a name match would be a real bypass vector. The blocklist prunes during traversal, so blocklisting a compartment protects everything beneath it too.
Do not list the tenancy root
Every compartment descends from the tenancy root, so a root entry makes every possible
target refuse with target compartment ... is blocklisted. It buys no protection either:
the tenancy root is already rejected as a target by a separate refusal that no config key
can switch off. List the compartments you actually want to protect — production, shared
services, anything holding state you cannot rebuild.
regions¶
Resources are enumerated once per region. Include the tenancy's home region if you want IAM
coverage: Policy, DynamicGroup, TagNamespace, TagDefault and Compartment are
home-region-only and are enumerated once, in the home region, rather than once per region. Omit
it and those five types are scanned nowhere — the run warns, but the plan simply has nothing to
say about them. The home region is often not the region your credentials connect through.
Two polarities worth reading twice¶
Both of these have bitten someone. Neither is a bug.
settings.protect.min-age skips what is younger. It guards against deleting a resource
somebody is creating right now, in a compartment you were told was idle.
A dateOlderThan filter with value: "24h" protects what is younger than 24 hours. The
filter engine computes fieldTime + duration and compares against now, so a resource created an
hour ago lands in the future and matches the filter; one created a month ago does not.
Filters are per-compartment, deliberately¶
Each compartment resolves its own filter set — a filter written for one compartment never
silently applies to another. Within a compartment, the reserved __global__ key applies to
every resource type.
presets are named, reusable filter sets; a compartment opts into one by listing its name under
its own presets key. A preset is not applied to any compartment that does not name it.
filters:
ocid1.compartment.oc1..aaaaaaaaexamplesandboxcompartmentexampleexampleexamplex:
filters:
__global__:
- property: "tag:Persistent"
type: exact
value: "true"
A freeform or defined tag is addressed as tag:<key> — libnuke's own default tag prefix, which
is what the resource types here build their properties with. Earlier revisions of this page showed
freeform_tags.<key>, which never matches anything.
Scanning the tenancy root for the types that can only live there¶
A few OCI types exist nowhere but the tenancy root — DynamicGroup is the one implemented today,
because OCI refuses to create a dynamic group in any other compartment. Their own compartment is
therefore always the tenancy OCID, which the resolved in-scope set never contains, so by default
they are listed, dropped as out-of-scope, and no configuration can delete them.
tenancy-root-types names the types a run may scan and remove there. Absent or empty — the
default — admits nothing:
tenancy-root-types:
- DynamicGroup
This does not make the tenancy root a target: a --compartment-id naming the tenancy is still
refused before any API call, and the extra root scan is restricted to exactly the types named
here. resource-types.excludes still wins over an entry, protect-by-tag and min-age are still
evaluated, and the compartment blocklist is untouched.
Filters for that scan are keyed by the tenancy OCID, like any other compartment. To delete only the groups one tool created, invert a filter so everything else is protected:
filters:
ocid1.tenancy.oc1..aaaaaaaaexampletenancyexampleexampleexampleexamplexxx:
filters:
DynamicGroup:
- property: "tag:module"
type: exact
value: "terraform-oci-oke"
invert: true
The reasoning, and the alternatives it rejects, are in ADR-0003.
What a config cannot do¶
- It cannot make the tenancy root a valid target.
tenancy-root-typesadmits named types at the root; it does not let a run target it. - It cannot shorten OCI's 7–30 day vault and key deletion window, or the 1–30 day secret one. They are scheduled for deletion and then reported as residue, not as failures.
- It cannot turn compartment deletion back off once enabled:
--delete-compartmentscan only turnsettings.compartment.deleteon, never override it back off.
See What cannot be deleted for the platform limits that no configuration changes.
Reference¶
Generated from pkg/config/schema/config.schema.json — the same schema config validate uses,
so this table cannot disagree with what the tool accepts. Regenerate with
go run ./tools/generate-config-docs; CI runs it with -check.
A constraint cell reading — means the schema constrains nothing beyond the type.
Top-level keys¶
| Key | Type | Required | Constraints |
|---|---|---|---|
compartment-blocklist |
list of string | yes | at least 1 entry; each entry matches ^ocid1\.(compartment|tenancy)\.[a-z0-9.]+$ |
filters |
map of compartmentFilters |
no | — |
presets |
map of preset |
no | — |
regions |
list of string | yes | at least 1 entry |
resource-types |
object (see below) | no | no other keys allowed |
settings |
object (see below) | no | — |
tenancy-id |
string | yes | matches ^ocid1\.tenancy\.[a-z0-9.]+$ |
tenancy-root-types |
list of string | no | — |
Nested objects¶
resource-types¶
| Key | Type | Required | Constraints |
|---|---|---|---|
excludes |
list of string | no | — |
includes |
list of string | no | — |
settings¶
| Key | Type | Required | Constraints |
|---|---|---|---|
compartment |
compartmentSettings |
no | — |
protect |
protectSettings |
no | — |
vault |
vaultSettings |
no | — |
compartmentFilters¶
| Key | Type | Required | Constraints |
|---|---|---|---|
filters |
filterMap |
no | — |
presets |
list of string | no | — |
compartmentSettings¶
| Key | Type | Required | Constraints |
|---|---|---|---|
delete |
boolean | no | — |
filter¶
Accepts 2 shapes.
As a string.
As an object.
| Key | Type | Required | Constraints |
|---|---|---|---|
group |
string | no | — |
invert |
boolean | no | — |
property |
string | yes | — |
type |
string | yes | one of exact, glob, regex, contains, dateOlderThan, dateOlderThanNow, suffix, prefix, In, NotIn |
value |
string | no | — |
values |
list of string | no | — |
filterMap¶
map of list of filter.
preset¶
| Key | Type | Required | Constraints |
|---|---|---|---|
filters |
filterMap |
no | — |
protectSettings¶
| Key | Type | Required | Constraints |
|---|---|---|---|
min-age |
string | no | matches ^([0-9]+(ns|us|µs|ms|s|m|h))+$ |
tags |
list of object (see below) | no | each entry no other keys allowed |
vaultSettings¶
| Key | Type | Required | Constraints |
|---|---|---|---|
deletion-window-days |
integer | no | between 7 and 30 |
secret-deletion-window-days |
integer | no | between 1 and 30 |