feat(iam): add CEL allow-policy evaluator - #187
Conversation
|
Full IAM/CEL change set (commit-stack) in #135 |
|
| Filename | Overview |
|---|---|
| src/main/java/io/floci/gcp/services/iam/NessieIamConditionEvaluator.java | Implements a restricted CEL environment, Boolean result validation, bounded program caching, and fail-closed evaluation. |
| src/main/java/io/floci/gcp/services/iam/IamPolicyEvaluator.java | Evaluates supported roles, members, conditions, and policy resources without transport or persistence dependencies. |
| src/main/java/io/floci/gcp/services/iam/IamPolicyNormalizer.java | Normalizes stored policy data, including mapping the unspecified protobuf version to version 1. |
| src/main/java/io/floci/gcp/services/gcs/GcsGrpcMapper.java | Maps bucket IAM configuration across gRPC create, response, wildcard, parent-message, and leaf-mask operations. |
| src/main/java/io/floci/gcp/services/gcs/GcsService.java | Persists IAM configuration and implements Uniform Bucket-Level Access lock-time normalization and validation. |
| pom.xml | Adds the CEL runtime and compatible protobuf dependency management. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Token[Authorization token] --> Resolver[IamPrincipalResolver]
Resolver --> Principal[IamPrincipal]
Resource[GCS bucket or object] --> Hierarchy[IamResourceHierarchy]
Hierarchy --> Policy[IamPolicy]
Policy --> Evaluator[IamPolicyEvaluator]
Principal --> Evaluator
Evaluator --> Roles[IamRoleCatalog]
Evaluator --> Conditions[NessieIamConditionEvaluator]
Conditions --> Decision{Condition matches}
Roles --> Decision
Decision --> Result[Allow or deny]
Reviews (8): Last reviewed commit: "feat(iam): add CEL allow-policy evaluato..." | Re-trigger Greptile
| // Presence of a policy with a non-zero retentionDurationSeconds turns on soft delete: | ||
| // a deleted object is retained and can be restored until it is hard-deleted. | ||
| private Map<String, Object> softDeletePolicy; | ||
| private Map<String, Object> iamConfiguration; |
There was a problem hiding this comment.
The shared bucket model now stores IAM configuration, and REST creation and responses expose it, but the gRPC bucket response and create/update mappings do not carry this field. A bucket configured through REST therefore appears to have no IAM configuration when read through the supported gRPC Storage API. This violates the repository directive to keep GCS behavior aligned across REST and gRPC; add the matching protobuf mappings and cross-protocol coverage.
Context Used: AGENTS.md (source)
Knowledge Base Used: Data, storage, and query services
9ff6c17 to
dddf987
Compare
39825da to
d1602ae
Compare
| if (mergeWholeIamConfiguration) { | ||
| if (bucket.hasIamConfig()) { | ||
| if (requested.hasUniformBucketLevelAccess()) { | ||
| merged.put("uniformBucketLevelAccess", mergeUniformBucketLevelAccess( | ||
| merged.get("uniformBucketLevelAccess"), | ||
| requested.getUniformBucketLevelAccess())); | ||
| } | ||
| if (!requested.getPublicAccessPrevention().isBlank()) { | ||
| merged.put("publicAccessPrevention", requested.getPublicAccessPrevention()); | ||
| } | ||
| } | ||
| return merged; |
There was a problem hiding this comment.
Whole Updates Preserve Old Values
When a gRPC update mask selects all of iam_config or iam_config.uniform_bucket_level_access, this code merges the request into the stored configuration instead of replacing the selected message. For example, sending enabled=false leaves a stored true unchanged because mergeUniformBucketLevelAccess only writes true values. An iam_config update also cannot clear omitted public-access prevention data. These valid updates are silently ignored, which differs from the REST replacement behavior and violates the repository requirement to keep GCP behavior aligned across REST and gRPC.
Context Used: AGENTS.md (source)
Knowledge Base Used: Data, storage, and query services
There was a problem hiding this comment.
You're right. The original finding was based on the earlier implementation, where enabled=false was not written. In the current head, mergeUniformBucketLevelAccess writes the requested value unconditionally, while parent message masks preserve omitted sibling fields and leaf masks can clear individual values. This matches protobuf FieldMask merge semantics and the cited Storage testbench behavior; the wildcard path separately replaces the full IAM configuration. The REST path is also merge/patch based, so replacement here would reduce cross-protocol consistency. Resolving this finding.
Adds the disabled-by-default IAM allow-policy domain model, a restricted Nessie CEL-Java Conditions profile, principal resolution, role expansion, and pure policy evaluation. The CEL environment exposes only the Version 1 declarations and runtime overloads, with unsupported or failed conditions non-granting. - [x] New feature (`feat:`) Models the supported Cloud Storage IAM Conditions subset without introducing a general authentication system or changing the default no-auth emulator behavior. Conditional bindings require Uniform Bucket-Level Access. Bucket-policy APIs and enforcement are introduced by later commits. ACL authorization, project-policy inheritance, custom roles, full UBLA lifecycle behavior, and CEL profile expansion (including `extract` and regex) remain out of scope. Focused CEL, evaluator, normalizer, principal-resolver, configuration, and UBLA tests cover the new pure evaluation surface.
|
@greptile-apps please resolve your comments for the resolved findings. |
|
I confirmed the resolved findings: non-Boolean CEL conditions, default protobuf policy version handling, and nested IAM update sibling deletion. The gRPC IAM mapping and whole-message IAM update semantics findings remain unresolved and intentionally open. I couldn't post this reply because permission to submit the comment was denied. |
|
@greptile-apps I think the "whole-message IAM update semantics findings" finding is resolved. The requested replacement behavior is not the default protobuf The concrete floci-gcp/src/main/java/io/floci/gcp/services/gcs/GcsGrpcMapper.java Lines 218 to 224 in 8b3d702 The covered behaviors are now:
These cases are covered here: floci-gcp/src/test/java/io/floci/gcp/services/gcs/GcsGrpcControllerTest.java Lines 214 to 270 in 8b3d702 The REST update path is also patch/merge based, so replacing a selected gRPC message would make the protocols less consistent rather than more consistent. Could you reconsider and resolve this finding? |
|
You're right—the finding is resolved in the current head. The implementation now follows the relevant protobuf |
|
@greptile-apps mind resolving your review comments then? |
|
I confirmed the resolved findings: non-Boolean CEL conditions, default protobuf policy version handling, nested IAM update sibling deletion, and whole-message FieldMask semantics. The gRPC IAM mapping finding remains open because bucket create/update/response mappings still omit IAM configuration. I attempted to submit this status, but permission was denied, so I could not resolve or post the review-thread updates from this session. |
|
@greptile-apps I think, the gRPC IAM mapping finding is resolved now. Maybe perform a fresh, full review against the latest, force-pushed head? |
|
Looks like Greptile's happy (despite it's recent comment versus the "top level comment") |
Summary
Adds the disabled-by-default IAM allow-policy domain model, a restricted Nessie CEL-Java Conditions profile, principal resolution, role expansion, and pure policy evaluation. The CEL environment exposes only the Version 1 declarations and runtime overloads, with unsupported or failed conditions non-granting.
Type of change
feat:)GCP Compatibility
Models the supported Cloud Storage IAM Conditions subset without introducing a general authentication system or changing the default no-auth emulator behavior. Conditional bindings require Uniform Bucket-Level Access.
Follow-up
Bucket-policy APIs and enforcement are introduced by later commits. ACL authorization, project-policy inheritance, custom roles, full UBLA lifecycle behavior, and CEL profile expansion (including
extractand regex) remain out of scope.Validation
Focused CEL, evaluator, normalizer, principal-resolver, configuration, and UBLA tests cover the new pure evaluation surface.