Skip to main content
Operation roles let you assign a specific role to each individual operation the Nuon runner performs, such as provisioning your sandbox, deploying a component, or running an action, instead of relying on a single all-purpose maintenance role. The result is granular, least-privilege access control with no changes required to your customers’ cloud accounts.

Why Use Operation Roles?

Your deploy workflow might need lambda:CreateFunction and lambda:UpdateFunctionCode. Your teardown workflow only needs lambda:DeleteFunction. With a shared maintenance role both permissions are always present; with operation roles each workflow gets exactly what it needs. Some concrete use cases:
  • Separate deploy vs teardown: prevent accidental deletion by ensuring your deploy role cannot delete resources
  • Tighter sandbox permissions: provision with a broad Terraform role and deprovision with a narrow destroy-only role
  • Emergency break-glass: run a privileged action role for incident response without elevating all action runs
  • Audit-friendly access: separate CloudTrail events per role make it easy to see which operation touched which resource

Role Selection Precedence

When a run starts, the runner selects a role by walking this chain from highest to lowest priority:
PrioritySourceScope
1 (highest)Runtime override (--role flag / dashboard selection)Any operation
2Break-glass role (break_glass_role field on action config, deprecated)Actions only
3Entity role (inline operation_roles block or role field)Single entity
4Matrix rule (operation_roles.toml principal + operation)App-wide
5 (lowest)Default role (permissions.toml provision_role, deprovision_role, or maintenance_role)App-wide
The first match wins. If nothing matches the run fails.

Defining Custom Roles

Any role used in an operation role assignment must be declared in permissions.toml with type = "custom" so it is provisioned in the customer’s CloudFormation stack:
permissions.toml
[[roles]]
type        = "custom"
name        = "{{.nuon.install.id}}-deploy-role"
description = "Role for Lambda deployments"

[[roles.policies]]
type     = "inline"
contents = """
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["lambda:CreateFunction", "lambda:UpdateFunctionCode"],
      "Resource": "*"
    }
  ]
}
"""

Configuring Entity Roles

Entity roles are defined inline on the individual config file. They take precedence over matrix rules.

Sandbox (sandbox.toml)

Use an [[operation_roles]] array to map sandbox operations to roles.
sandbox.toml
[[operation_roles]]
operation = "provision"
role      = "{{.nuon.install.id}}-provision-role"

[[operation_roles]]
operation = "reprovision"
role      = "{{.nuon.install.id}}-provision-role"

[[operation_roles]]
operation = "deprovision"
role      = "{{.nuon.install.id}}-destroy-role"
Valid operations for sandbox: provision, reprovision, and deprovision.

Components (components/<name>.toml)

Use the same [[operation_roles]] array on any component config file.
components/my_lambda.toml
[[operation_roles]]
operation = "deploy"
role      = "{{.nuon.install.id}}-deploy-role"

[[operation_roles]]
operation = "teardown"
role      = "{{.nuon.install.id}}-teardown-role"
Valid operations for components: deploy and teardown.

Actions (actions/<name>.toml)

Actions use a single top-level role field (not an array). break_glass_role is deprecated and should no longer be used.
actions/db_migration.toml
name    = "db_migration"
timeout = "10m"
role    = "{{.nuon.install.id}}-migration-role"

[[triggers]]
type = "manual"

[[steps]]
name    = "run-migration"
command = "./migrate.sh"
Valid operation for actions: trigger.

Configuring Matrix Rules (operation_roles.toml)

The operation_roles.toml file defines app-level rules that apply across all installs. Rules are matched by principal (which entity is performing the operation) and operation name. Create a file named operation_roles.toml at the root of your app config:
operation_roles.toml
type = "matrix"

[[rules]]
principal = "nuon::component:my_lambda"
operation = "deploy"
role      = "{{.nuon.install.id}}-lambda-deploy-role"

[[rules]]
principal = "nuon::component:my_lambda"
operation = "teardown"
role      = "{{.nuon.install.id}}-lambda-teardown-role"

[[rules]]
principal = "nuon::sandbox"
operation = "provision"
role      = "{{.nuon.install.id}}-provision-role"

[[rules]]
principal = "nuon::sandbox"
operation = "deprovision"
role      = "{{.nuon.install.id}}-destroy-role"

[[rules]]
principal = "nuon::action:db_migration"
operation = "trigger"
role      = "{{.nuon.install.id}}-migration-role"

Principal Format

EntityPrincipal
Specific componentnuon::component:<name>
All componentsnuon::component:*
Sandboxnuon::sandbox
Specific actionnuon::action:<name>
All actionsnuon::action:*
The wildcard * matches any entity of that type, making it easy to set a default role for all components or all actions without listing each one.

Role Name Templating

Role names support the same Go template syntax used elsewhere in Nuon config:
role = "{{.nuon.install.id}}-deploy-role"
Common template variables:
VariableDescription
{{.nuon.install.id}}Install ID, ensures each install gets its own role
{{.nuon.install.sandbox.outputs.<key>.name}}Sandbox stack output values
The rendered role name must match a role defined in permissions.toml (either a standard role or a custom_roles entry).

Syncing with the CLI

After adding or changing operation role config, sync your app to push the updated config to Nuon:
nuon apps sync
This syncs all the configs with the control plane, including operation_roles.toml and any inline operation_roles blocks.

Runtime Role Override

You can override the role for a specific run without changing any config file.

CLI

Pass --role <role-name> when triggering a sandbox or component operation:
# Override role for a manual action run
nuon actions create-run -w <action-workflow-id> -i <install-id> --role my-custom-role

Dashboard

On the install page, before triggering a run, use the role selector in the run options panel to choose an alternative role from those available in the install’s CloudFormation stack.

Viewing Configured Roles

In the Nuon dashboard, navigate to your install and open the Components or Actions tab. Each entity shows the currently configured role.

Next Steps