aws-ca-publish-is-modify-code
Publishing a package version to a CodeArtifact repository injects code into every consumer that installs the package - supply-chain CanModifyCode.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?repository) ==
ArtifactRepository
provider_type(?repository) in [AWS::CodeArtifact::Repository, AWS::CodeArtifact::Package]
effective permission includes codeartifact:PublishPackageVersion on ?repository (or the package ARN within it)
emit
| source type | Identity |
|---|---|
| target type | ArtifactRepository |
| source | ?principal |
| target | ?repository |
| permissions | codeartifact:PublishPackageVersion codeartifact:GetAuthorizationToken? codeartifact:PutPackageMetadata? |
| conditions | iam_permission resource_policy |
| state logic | ACTIVE when the principal holds effective codeartifact:PublishPackageVersion on the repository (or package) scope AND codeartifact:GetAuthorizationToken on the domain — both required for an actual publish (the token is the HTTP bearer credential for the package-manager endpoint). CONDITIONAL(resource_policy) when the permission is granted via a cross-account resource policy and the caller's identity policy has not been confirmed to also allow the action (standard cross-account IAM evaluation: both sides must allow). BLOCKED when an SCP or permission boundary explicitly denies codeartifact:PublishPackageVersion or codeartifact:GetAuthorizationToken. When the scope is a SPECIFIC PACKAGE ARN (not a wildcard), restrict this edge to that package node; the broader repository node is only appropriate when the resource scope covers all packages (`package/domain/repo/*` or `*`). |
Narrative
{principal.name} can publish a package version to {repository.name} (codeartifact:PublishPackageVersion + codeartifact:GetAuthorizationToken). Any consumer that resolves and installs this package version will execute the attacker-controlled code in its build or runtime environment, acquiring CanModifyCode over each such consumer (cicd-chains / container-chains propagate this to CanExecuteAs the consumer's execution identity).
Raw rule rules/derived/aws/codeartifact.yaml
id: aws-ca-publish-is-modify-code
emits: CanModifyCode
description: "Publishing a package version to a CodeArtifact repository injects code into every consumer\
\ that installs the package \u2014 supply-chain CanModifyCode."
match:
- - principal: null
- HasPermission
- repository: null
where:
- node_type(?repository) == ArtifactRepository
- provider_type(?repository) in [AWS::CodeArtifact::Repository, AWS::CodeArtifact::Package]
- effective permission includes codeartifact:PublishPackageVersion on ?repository (or the package ARN
within it)
emit:
source_type: Identity
target_type: ArtifactRepository
source: ?principal
target: ?repository
permissions:
- codeartifact:PublishPackageVersion
- codeartifact:GetAuthorizationToken?
- codeartifact:PutPackageMetadata?
conditions:
- iam_permission
- resource_policy
state_logic: "ACTIVE when the principal holds effective codeartifact:PublishPackageVersion on the repository\
\ (or package) scope AND codeartifact:GetAuthorizationToken on the domain \u2014 both required for\
\ an actual publish (the token is the HTTP bearer credential for the package-manager endpoint). CONDITIONAL(resource_policy)\
\ when the permission is granted via a cross-account resource policy and the caller's identity policy\
\ has not been confirmed to also allow the action (standard cross-account IAM evaluation: both sides\
\ must allow). BLOCKED when an SCP or permission boundary explicitly denies codeartifact:PublishPackageVersion\
\ or codeartifact:GetAuthorizationToken. When the scope is a SPECIFIC PACKAGE ARN (not a wildcard),\
\ restrict this edge to that package node; the broader repository node is only appropriate when the\
\ resource scope covers all packages (`package/domain/repo/*` or `*`)."
confidence: 0.9
derived_from:
- effective codeartifact:PublishPackageVersion on ?repository (permission evaluator)
- effective codeartifact:GetAuthorizationToken on the domain containing ?repository
false_positive_note: "codeartifact:GetAuthorizationToken alone (without PublishPackageVersion) is NOT\
\ CanModifyCode \u2014 it only authenticates; do not emit this edge for auth-token- only grants. \
\ codeartifact:ReadFromRepository is read-only; never equate it with write access. When PublishPackageVersion\
\ is scoped to a specific package ARN (e.g., `package/domain/repo/npm//react`), emit CanModifyCode\
\ targeting that package node, not the entire repository. Maven publish also requires codeartifact:PutPackageMetadata;\
\ without it, the publish will fail -> downgrade to POTENTIAL if PutPackageMetadata is absent on a\
\ Maven repository. NuGet publish also requires codeartifact:ReadFromRepository on the repository.\
\ Honor iam:ResourceTag / aws:RequestedRegion / aws:PrincipalOrgID conditions on resource policies\
\ that narrow the effective grant."
narrative: '{principal.name} can publish a package version to {repository.name} (codeartifact:PublishPackageVersion
+ codeartifact:GetAuthorizationToken). Any consumer that resolves and installs this package version
will execute the attacker-controlled code in its build or runtime environment, acquiring CanModifyCode
over each such consumer (cicd-chains / container-chains propagate this to CanExecuteAs the consumer''s
execution identity).'