Entitlements, operations, and IAM
How CCE represents API actions (for example S3 read vs write), what to expect when one function uses multiple operations, and how to turn scan output into least-privilege IAM—without misconfiguring lenses.
What
An entitlement is one mapped call site in JSON:
| Field | Meaning |
|---|---|
provider |
Cloud or custom label (AWS, PLATFORM, TECH_DEBT, …) |
resource |
Service or module (s3, kms, platform package segment, …) |
operation |
API action or method segment (GetObject, PutObject, Sync, …) |
file / line |
Where the call appears in source |
method |
Fully qualified name CCE extracted |
parent_function |
Enclosing function (when available) |
Model: one static call site → one operation per entitlement row. CCE does not emit a single row with multiple operations (for example GetObject + PutObject combined).
The built-in cloud mapper derives operation from the SDK method name at that line (cloud entitlements).
Why
IAM and PoLP need the set of actions code can invoke—not a single label per business function. A handler that downloads and uploads artifacts needs both s3:GetObject and s3:PutObject in policy (plus any others found in scan).
Understanding the one-call-site-one-operation model avoids:
- Broken lens YAML that tries to “declare” read+write in one rule
- Under-provisioned roles when only a wrapper method appears in app code
- Confusion when
cce diffreports two new entitlements for one logical feature change
CCE inventories code; it does not compute effective IAM permissions, resource ARNs, or bucket names from policies alone (KNOWN_LIMITATIONS).
One function, S3 read and S3 write (direct SDK calls)
What happens: If SyncArtifact() calls GetObject and PutObject (or equivalent SDK methods), the scan produces two entitlements—typically different lines, same or different parent_function.
cce -folder . -language AUTO -filter cloud -format json -output entitlements.json
Example rows:
{
"provider": "AWS",
"resource": "s3",
"operation": "GetObject",
"file": "internal/storage/artifact.go",
"line": 42,
"parent_function": "SyncArtifact"
}
{
"provider": "AWS",
"resource": "s3",
"operation": "PutObject",
"file": "internal/storage/artifact.go",
"line": 58,
"parent_function": "SyncArtifact"
}
Why this is correct: Least privilege is defined over API actions actually invoked. Two calls → two facts → union when building a policy.
How to build IAM from the report: Aggregate unique operations for the scope you need (function, package, or whole repo):
# All S3 operations used by one function
jq '[.entitlements[]
| select(.resource == "s3" and .parent_function == "SyncArtifact")
| .operation] | unique' entitlements.json
# All S3 operations in the repo
jq '[.entitlements[] | select(.resource == "s3") | .operation] | unique' entitlements.json
Map each operation to IAM action names your policy generator expects (for example GetObject → s3:GetObject).
cce diff: Each entitlement is keyed by (provider, resource, operation, file, line, method). Adding a write path without a read path shows one new row—the new call site—not “dual operation on same key.”
Read vs write in custom lenses
What: Separate Grok rules (or prefix + captured operation) per operation family—not one rule that assigns two operations.
Why: The mapper returns a single MappedResource per call; the first matching rule wins when several could apply.
How: Example for AWS SDK for Go v2 S3 client methods:
definition:
language:
go:
- name: "S3 read APIs"
prefix: "github.com/aws/aws-sdk-go-v2/service/s3."
provider: AWS
rule: "github\\.com/aws/aws-sdk-go-v2/service/s3\\.(?<operation>GetObject|HeadObject|ListObjectsV2)"
- name: "S3 write APIs"
prefix: "github.com/aws/aws-sdk-go-v2/service/s3."
provider: AWS
rule: "github\\.com/aws/aws-sdk-go-v2/service/s3\\.(?<operation>PutObject|DeleteObject|CreateMultipartUpload)"
Each physical GetObject / PutObject invocation still produces one row with the captured operation.
Put more specific rules before generic ones to avoid “multiple language definitions matched” warnings (Custom lens YAML).
For runbooks that care about read vs write (KMS decrypt vs encrypt, etc.), filter on operation after scan — see runbook-targeting.
Wrappers and facades
What: Application code calls platform.Storage.Sync(); S3 SDK calls live inside the platform library.
Why it matters: CCE only maps call sites visible in the scanned tree. You may see one entitlement for Sync, not GetObject + PutObject, unless those SDK calls appear in analyzed files.
How to handle it:
| Approach | When |
|---|---|
| Scan the platform SDK repository (or vendored copy) | Ground truth for what the wrapper invokes |
| Add lens rules for the wrapper FQN | Inventory adoption; use a single operation label (e.g. Sync) for reporting |
| Maintain a wrapper → IAM action list outside CCE | Policy templates for known composite helpers |
| Extend lens for wrapper shape | See prowler for non-standard client patterns |
Do not expect one lens rule to emit both read and write for a single wrapper method name—use multiple visible SDK call sites or external IAM documentation.
What CCE does not do (IAM synthesis)
| Expectation | Reality |
|---|---|
One entitlement row with operations: [GetObject, PutObject] |
Not supported — aggregate in your tooling |
| Infer read+write from a high-level method without child calls | Not supported — static call graph only |
| Effective IAM / SCP / permission boundaries | Out of scope — code invocation inventory only |
| Bucket/key ARNs from all SDK calls | Limited; some patterns use extract_resource_from — see Custom lens YAML |
Decision guide
| Your situation | What to do |
|---|---|
Function calls GetObject and PutObject in app code |
Default cce -filter cloud; union operations for IAM |
| CI gate on new cloud usage | cce diff + optional policy YAML (recipes) |
| Custom lens for internal SDK | One rule per detectable method/pattern; enterprise guide |
| Single wrapper, need both S3 read and write in policy | Scan SDK implementation or document explicit action list; don’t overload one lens row |
| Platform vs direct cloud adoption | platform-adoption lens |
Related
- Cloud entitlements (repo usage guide)
- Pre-deploy IAM review (repo usage guide)
- Enterprise lenses and catalogs
- Guides overview
- Custom lens YAML