feat(iam) policy evaluation stack (WIP!) - #135
Conversation
96040ce to
19613cc
Compare
449e15d to
8830baf
Compare
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.
## Summary Preserves the canonical service-account principal when STS exchanges a valid Floci-issued impersonated token for a downscoped token. Principal resolution keeps the downscoped marker so GCS can apply Credential Access Boundary checks before later IAM evaluation. ## Type of change - [x] New feature (`feat:`) ## GCP Compatibility Carries identity attribution without storing the source bearer token. External source tokens remain principal-less, and invalid or expired Floci-issued sources retain their existing OAuth-shaped failure behavior. ## Follow-up No IAM policy is added to STS itself. Recursive downscoping remains rejected until CAB-rule intersection can prove that a requested boundary cannot broaden existing authority. ## Validation Focused credential-token, principal-resolver, and STS REST tests cover propagation, anonymous external sources, invalid sources, expiry, and recursive-exchange rejection.
## Summary Adds bucket IAM policy validation, policy bootstrap on bucket creation, IAM-aware `testIamPermissions`, and opt-in authorization checks for supported bucket operations. Enforcement stays disabled by default and uses the shared policy evaluator only when explicitly enabled. ## Type of change - [x] New feature (`feat:`) ## GCP Compatibility Preserves disabled-mode behavior, requires Uniform Bucket-Level Access for conditional bindings, and rejects every bucket patch that would remove or disable UBLA while such bindings remain configured. Policy validation and response shapes use existing Cloud Storage IAM endpoints. ## Follow-up Project-scoped bucket create/list authorization, ACL behavior while UBLA is active, and the complete UBLA lifecycle remain deliberately deferred. ## Validation Focused REST integration tests cover bucket IAM get/set/testPermissions, policy bootstrap, conditional-policy validation including absent, null, and partial UBLA patches, disabled-mode continuity, and enforce-mode permissions.
## Summary Applies IAM permission checks to the audited Cloud Storage object surface: JSON and XML reads, updates, deletes, uploads, listing, compose, copy, rewrite, move, and restore. Source and destination authorization is ordered before mutations, including replacement-delete checks. ## Type of change - [x] New feature (`feat:`) ## GCP Compatibility Keeps existing GCS endpoint shapes and CAB ordering while mapping each supported operation to its required object permissions. Restore requires `storage.objects.restore` and `storage.objects.create`, plus `storage.objects.delete` when replacing a live object. Denied requests are verified to leave no storage side effect. ## Follow-up ACL endpoints, signed-URL identity, batch framing, retention/context-specific permissions, and hierarchical-namespace behavior are excluded until they have separately scoped permission mappings and compatibility evidence. ## Validation Focused REST integration tests cover allow and deny cases for JSON/XML operations, alternate downloads, XML listing and deletion, multipart and resumable uploads, restore, source/destination flows, replacement uploads, and no-side-effect denials.
Completes CAB-first IAM evaluation for principal-bearing downscoped credentials, accepts the Storage client default policy version, documents the boundary, and adds an enforce-mode Java SDK compatibility path from IAM Credentials through `DownscopedCredentials` to Cloud Storage. - [x] New feature (`feat:`) A downscoped token minted from a valid Floci-issued impersonated token retains that service-account identity for GCS IAM evaluation only after its CAB permits the request. The normal compatibility matrix remains disabled-mode; the focused SDK scenario restarts only the Java emulator in enforce mode. The IAM, GCS, README, service-index, and setup documentation now distinguish default no-auth behavior from the supported enforce-mode REST surface. External source tokens remain principal-less, nested downscoping remains rejected, and CAB parsing remains limited to the documented `startsWith` forms. Broader CAB expressions and rule intersection require a separate compatibility design. Focused token, STS-to-GCS, policy-normalization, object-authorization, and Java SDK compatibility coverage verifies allowed access plus distinct CAB and IAM denials.
8830baf to
8b4ca5d
Compare
|
@greptile-apps please review |
|
| Filename | Overview |
|---|---|
| src/main/java/io/floci/gcp/services/gcs/GcsGrpcController.java | Adds gRPC IAM-configuration update support but bypasses the conditional-policy transition validation used by REST. |
| src/main/java/io/floci/gcp/services/iam/IamBucketPolicyService.java | Coordinates bucket policies and conditions, but incorrectly interprets unrelated partial IAM configuration patches as UBLA removal. |
| src/main/java/io/floci/gcp/services/iam/GcsIamAuthorizationService.java | Composes CAB and IAM permission checks and defers overwrite-delete authorization for atomic evaluation. |
| src/main/java/io/floci/gcp/services/gcs/GcsService.java | Adds atomic overwrite checks and server-managed UBLA lock normalization. |
| src/main/java/io/floci/gcp/services/iam/NessieIamConditionEvaluator.java | Implements a bounded, cached CEL environment for supported IAM conditions. |
| src/main/java/io/floci/gcp/services/credentials/CredentialTokenService.java | Preserves impersonated principals in downscoped tokens and rejects recursive downscoping. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
R[Incoming GCS request] --> P{Protocol}
P -->|REST object or bucket| C[CAB and IAM authorization]
C --> E[Resolve principal and bucket policy]
E --> A{Permission granted?}
A -->|No| D[Return permission denied]
A -->|Yes| M[Execute GCS mutation or read]
P -->|gRPC bucket update| F[Resolve FieldMask into IAM configuration]
F --> U[Persist through GcsService]
C --> V[REST UBLA and conditional-policy validation]
V --> M
F -. missing equivalent validation .-> U
Reviews (1): Last reviewed commit: "feat(iam): support IAM-aware downscoped ..." | Re-trigger Greptile
| return GcsGrpcMapper.toProto(service.updateBucketWithResolvedFields(bucketId, | ||
| GcsGrpcMapper.bucketUpdateFields( | ||
| request.getBucket(), request.getUpdateMask().getPathsList()))); | ||
| current, request.getBucket(), request.getUpdateMask().getPathsList()))); |
There was a problem hiding this comment.
gRPC Bypasses Policy Validation
The gRPC UpdateBucket path writes the resolved IAM configuration without calling validateIamConfigurationUpdate, while both REST update paths perform that validation. A gRPC client can therefore disable uniform bucket-level access while conditional IAM bindings remain stored, leaving the bucket in an invalid state that REST rejects. Route the resolved gRPC patch through the same validation before persisting it. This also violates the repository directive to check compatibility across alternate gRPC and REST protocol paths.
Context Used: AGENTS.md (source)
| if (uniformBucketLevelAccessEnabled(bucket) | ||
| && patch != null | ||
| && patch.containsKey("iamConfiguration") | ||
| && !uniformBucketLevelAccessEnabled(patch.get("iamConfiguration")) | ||
| && hasConditionalBindings(getPolicy(bucket))) { |
There was a problem hiding this comment.
This check treats every partial iamConfiguration patch that does not explicitly contain uniformBucketLevelAccess.enabled=true as disabling UBLA. On a bucket with UBLA and conditional bindings, a valid patch that only changes publicAccessPrevention is rejected even though GcsService.updateBucket merges the patch and preserves the current UBLA setting. Check whether the patch actually removes or disables UBLA, or validate the merged configuration instead.
No description provided.