feat(iam/agent): split agent role into agent + permissions roles#397
Merged
Conversation
…ns roles Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply privilege separation to the agent IAM module. The IRSA agent role
no longer carries the workload policies directly; it only holds an
sts:AssumeRole policy and assumes a separate permissions role that holds
the Route53/EKS/ELB/AVP policies and trusts only the agent role.
- agent role: only sts:AssumeRole (permissions role + assume_role_arns)
plus additional_policies
- new permissions role (nullplatform-{cluster}-agent-permissions-role)
with the four workload policies attached, trusting the agent role
- ARNs derived from names + caller account id to avoid a circular
dependency between the two roles
- assume_role_policy is now always created (moved block migrates it from
the previous conditional [0] address)
- new permissions_role_name variable and
nullplatform_agent_permissions_role_arn output
BREAKING CHANGE: the IRSA token no longer has Route53/EKS/ELB/AVP
permissions directly. The agent must assume the permissions role (exposed
via the nullplatform_agent_permissions_role_arn output) to use them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add var.permissions_roles (map) to create additional permissions roles assumable by the agent role, on top of the default permissions role. - each entry creates an aws_iam_role via for_each, trusting only the agent role, with the given policy_arns attached - names/ARNs are computed from name + caller account id (like the default role) so the agent assume policy stays deterministic and free of circular dependencies - the agent sts:AssumeRole policy now targets the default permissions role + every extra role + assume_role_arns - new output nullplatform_agent_extra_permissions_role_arns (map of logical name to ARN) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sebastiancorrea81
approved these changes
Jun 19, 2026
The default permissions role (nullplatform_agent_permissions) and its workload
policies (Route53, ELB, EKS, AVP) are no longer created by this module. They are
now provisioned per-cluster by the k8s scope's OpenTofu module
(scopes: k8s/scope/tofu/iam/modules).
This module keeps only the agent IRSA role and its sts:AssumeRole policy, which
still authorizes assuming the permissions role by its conventional ARN
(nullplatform-{cluster_name}-agent-permissions-role). The output now returns
that computed ARN instead of a created resource.
Removed: nullplatform_agent_permissions role, its 4 policy attachments, the 4
workload policies, and the now-unused aws_region data source. Tests and README
updated accordingly.
NOTE: existing consumers will destroy the permissions role on next apply; the
scope module must create the replacement under the same conventional name.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Qué cambia
Aplica separación de privilegios al módulo
infrastructure/aws/iam/agent. El rol IRSA del agente deja de cargar las políticas de workload directamente: ahora solo tiene una políticasts:AssumeRoley asume un rol de permisos separado que concentra las políticas Route53/EKS/ELB/AVP y que confía únicamente en el rol agente. Además se agrega soporte para crear N roles de permisos adicionales víapermissions_roles.Arquitectura resultante
Detalles
sts:AssumeRole(rol default + roles extra +assume_role_arns) +additional_policies.aws_iam_roleque confía solo en el rol agente, con las 4 políticas de workload pegadas.var.permissions_roles(mapa) crea roles adicionales confor_each, cada uno confiando en el agente y con suspolicy_arnspegados.aws_caller_identitypara evitar la dependencia circular entre roles.assume_role_policyahora siempre se crea (antes condicional).movedblock migra el state denullplatform_assume_role_policy[0]→nullplatform_assume_role_policy.permissions_role_name,permissions_roles. Nuevos outputsnullplatform_agent_permissions_role_arn,nullplatform_agent_extra_permissions_role_arns.El token IRSA ya no tiene permisos Route53/EKS/ELB/AVP de forma directa. El agente debe asumir el rol de permisos (output
nullplatform_agent_permissions_role_arn) para usarlos. Coordinar el cambio del lado del runtime del agente.Testing
tofu fmt -check,tofu validate✅tofu test— 12/12 pass (incluye naming, trust, attachments, assume targeting del rol default, suma deassume_role_arns, y los roles extra: creación condicional, naming/override, trust y inclusión en la assume policy).Spec de diseño:
docs/superpowers/specs/2026-06-19-iam-agent-role-split-design.md🤖 Generated with Claude Code