feat: dynamic assume-role support for the AWS S3 service (+ IAM fixes & cleanup)#11
Draft
davidf-null wants to merge 15 commits into
Draft
feat: dynamic assume-role support for the AWS S3 service (+ IAM fixes & cleanup)#11davidf-null wants to merge 15 commits into
davidf-null wants to merge 15 commits into
Conversation
When assume_role_arn is set, the agent's base credentials (IRSA or static) are used only to call sts:AssumeRole; all subsequent AWS calls (CLI + Terraform) run under the target role. When empty, IRSA is used directly, preserving backward compatibility for single-account setups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add create_role and trusted_arns variables to optionally create an IAM role with a configurable trust policy, allowing other roles to assume it via sts:AssumeRole. Outputs role_arn and role_name expose the created role. Existing role_name behavior is unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…UTPUT_DIR Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…PATH Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uration) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1bb29fe to
a98e2da
Compare
…revent self-assume failure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…build_context Removed the ACTION_SOURCE guard around link variable extraction — the check was never true because ACTION_SOURCE is never set, causing LINK_ID and related outputs declared in link.yaml to be missing, which fails the workflow step. Variables now always extracted from $CONTEXT using jq defaults (empty string for non-link actions), preserving backward compatibility. Also redirected error messages from stderr to stdout so they appear in NP workflow logs, and added a DEBUG dump of the providers response to aid future diagnosis. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hanges
Security/hygiene pass to keep the published service account-agnostic:
- Delete local np-api-skill.{key,key.admin,token} files and ignore
np-api-skill.*, *.key, *.token, *.pem and .claude/ so credentials can
never be committed.
- Clear the hardcoded testing ARN in aws-s3-bucket/values.yaml; assume_role_arn
now defaults to "" (IRSA), with the account-specific ARN provided per
installation via --overrides-path.
- README: document credential isolation before assume role (self-assume
prevention), expand the agent IAM permissions section (three policies + why
the full s3:Get* read set is required), and clarify the account-agnostic note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The agent now resolves the IAM role ARN to assume from the "AWS IAM" provider (category Identity & Access Control, spec aws-iam-configuration) declared in nullplatform, matching its arns list by selector. Precedence: env var -> provider -> values.yaml -> IRSA. - assume_role_lib (new): pure arn_for_selector_from_json + provider_arn_for_selector (list->read, since provider list omits deep attributes). - assume_role: rewritten with the precedence chain above. - build_context: derive ACCOUNT_NRN and selector BEFORE sourcing assume_role (previously sourced before NRN was available); export ASSUME_ROLE_NRN/SELECTOR. - build_permissions_context: same selector resolution for link actions, after the inherited-credentials unset. - values.yaml: new assume_role_selector (default service slug); assume_role_arn is now a fallback for local testing / back-compat. - tests: bash unit tests for both lib functions, using a fake np on PATH as a test double; fixtures use placeholder account/ARN values only. - README: auth section rewritten to document the provider and precedence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the assume-role logic out of build_context and build_permissions_context into a new standalone assume_role_step that runs as the first step of every aws workflow. The role is now assumed exactly once, up front, and the temporary credentials are exported and inherited (then re-exported) by all subsequent steps. Assuming once eliminates the double-assume that required unsetting and re-assuming credentials in build_permissions_context (the self-assume failure addressed in 5671ac6); that workaround is removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
a625b98 to
e39cba4
Compare
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.
Summary
Adds dynamic assume-role support to the AWS S3 dependency service so the agent
can run AWS operations under a per-service / cross-account IAM role instead of only
its base IRSA identity, plus the IAM-permission and link-workflow fixes found while
testing it, and a final security/docs hardening pass.
Changes
Dynamic assume role
assume_role_arninvalues.yaml. When set, the agent callssts:AssumeRolewith its IRSA identity and uses the temporary credentials for all subsequent AWS
calls (CLI + Terraform). Empty → IRSA is used directly.
build_permissions_context) unset anyinherited
AWS_*credentials before sourcingassume_role, so the call alwaysstarts from the IRSA identity and never tries to re-assume an already-assumed role
(self-assume failure).
Requirements module — optional role creation
create_role(bool) to optionally create the IAM role inside the module.trusted_arns(list) for the principals allowed tosts:AssumeRole.role_arn/role_nameoutputs. Backwards compatible: existingrole_namebehavior unchanged.IAM permission fixes (required by the AWS provider)
The provider refreshes the full bucket configuration on every plan, so the
bucket-management policy now grants the complete
s3:Get*read set:s3:GetReplicationConfiguration,s3:GetEncryptionConfiguration/s3:PutEncryptionConfiguration.Link / state fixes
build_context: always export the link context vars and surface errors to stderrfor visibility in NP logs.
tofu init -reconfigureto handle stale backend state inOUTPUT_DIR.Security & docs hardening
values.yaml;assume_role_arnnowdefaults to
""so the published service stays account-agnostic. Theaccount-specific ARN is provided per installation via
--overrides-path.np-api-skill.{key,key.admin,token}credential files and addednp-api-skill.*,*.key,*.token,*.pem,.claude/to.gitignoresocredentials can never be committed.
IAM permissions section (three policies + why the full read set is needed), and
clarified the account-agnostic override note.
Test plan
create_role = false+role_nameset → existing behavior unchangedcreate_role = true+trusted_arnspopulated → role created with correcttrust policy and all 3 policies attached;
role_arnoutput correctassume_role_arnempty → IRSA used directly end-to-endassume_role_arnset (cross-account) → create/update/link/unlink all rununder the assumed role; link actions do not hit a self-assume failure
assume_role_arn→ workflow aborts immediately (no IRSA fallback)s3:Get*read permissions🤖 Generated with Claude Code