Add access management: grants, groups, and org data sources - #11
Conversation
New org package: splitsecure_grant (per-resource tier grants, upsert semantics, PermissionDenied retry on create to absorb the creator-grant race), splitsecure_group (locally-managed groups with an authoritative member set), and data sources splitsecure_organization (Everyone-group S2R), splitsecure_org_member (by email), splitsecure_group (by name). Wires an OrgService client, extends examples/full with an access section, and regenerates docs. go.mod carries a dev-only replace to the sibling apis working tree; swap it for a pinned apis version before merge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- grant: tolerate no server-echo of RequiresReplace attrs by writing state from the plan on Create/Update (avoids a post-apply consistency failure if the server canonicalizes an s2r); extract the shared upsertGrant helper so Create/Update differ only by the auth retry. - group: tolerate NotFound when removing a member (matches DeleteGroup / DeleteGrant) so an already-gone principal doesn't wedge apply; drop dead UseStateForUnknown guards in Update. - extract a package-local clientFromProviderData helper used by all five resources/data sources' Configure. - extract the context-aware sleep into internal/wait and reuse it from the grant retry loop and the saml2 proposal poller. - tests: clientFromProviderData; member-removal NotFound tolerance and the non-NotFound failure path (via a minimal fake OrgService client). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A dedicated package for one context-aware sleep was more indirection than the small duplication warranted. Restore the inline timer/select in the grant retry loop and saml2's local sleep helper; drop internal/wait. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
pipe is failing because apis#14 is not merged yet |
Look up splitsecure_group strictly by group_s2r; drop the mutable, non-unique name path (the ListGroups scan and its ambiguity handling). Address the final code review: - fail closed on empty user_s2r, principal_s2r, and everyone_group_s2r instead of silently emitting an empty s2r into downstream sinks - grant Read refreshes only tier, preserving the config-owned RequiresReplace keys (consistent with Create/Update) - test fetchLocalGroup source rejection, the reconcileMembers add path, and the groupResource.Read null-vs-empty member branch - remove a duplicate source-mapping test; drop putGrantRetryingAuthz's unused return value Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
apis#14 merged (3a98224); swap the local `replace => ../apis` for the pinned pseudo-version so CI resolves the real public module instead of the sibling checkout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolves an org principal to its s2r by the email shown in the console, covering both users (via the member directory) and service accounts (the SA email's local part is its sa: s2r id, validated against GetServiceAccounts). No new backend RPC. The s2r is usable as a group member or grant grantee. examples/full now takes operator_emails and resolves them through the new data source instead of requiring raw s2rs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blank line before returns; fixes the CI lint failure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…in group example Addresses review feedback: - examples/full: variable declarations (org_s2r, team_s2r, operator_emails) moved out of main.tf into variables.tf; terraform.tfvars.example gains an operator_emails value; index doc embeds variables.tf so it stays complete. - examples/resources/splitsecure_group: reference members by console email via splitsecure_principal (user and service account) instead of raw s2rs. - Regenerated docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Swap the principal data source from a ListMembers roster scan plus client-side match (and client-side service-account email parsing) to a single server-side GetMembersByEmail call, which resolves users and service accounts alike. Bump the apis dep to the commit that adds the RPC. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The RPC now returns one Result per requested email (email + its matches) instead of a flat member list; splitsecure_principal reads results[0] for its single-email lookup. Bump the apis dep to the merged commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🔗 Linked repositories identifiedCodeRabbit considers these linked repositories for cross-repo context during reviews:
📜 Recent review details⏰ Context from checks skipped due to timeout. (3)
🧰 Additional context used🔀 Multi-repo contextLinked repositories findingsNo additional cross-repository context beyond the previously identified API contract findings was necessary. 🔇 Additional comments (1)
WalkthroughAdds OrgService-backed Terraform resources for grants and local groups, organization-related data sources, provider registration, client wiring, tests, examples, and generated documentation. ChangesOrganization capabilities
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Terraform
participant Provider
participant OrgService
participant OrganizationAPI
Terraform->>Provider: Configure organization resources and data sources
Provider->>OrgService: Create OrgService client
Terraform->>OrgService: Resolve organization, principals, and groups
OrgService->>OrganizationAPI: Execute organization RPCs
OrganizationAPI-->>OrgService: Return organization data
OrgService-->>Terraform: Return Terraform state
Terraform->>OrgService: Apply groups and permission grants
OrgService-->>Terraform: Return applied resource state
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/data-sources/principal.md`:
- Around line 5-11: Align principal descriptions with GetMembersByEmail: in
docs/data-sources/principal.md lines 5-11, regenerate the page from the schema
description and remove the direct service-account parsing claim from both
duplicated descriptions; in
examples/data-sources/splitsecure_principal/data-source.tf lines 1-4, state that
service-account emails are resolved through the member directory.
In `@splitsecure/client/client.go`:
- Line 53: Update the client setup around OrgService and its NewOrgServiceClient
construction to disable transport retries for mutation RPCs, including
CreateGroup, UpdateGroup, DeleteGroup, PutGrant, and DeleteGrant. Use a separate
non-retrying HTTP client or an RPC-specific CheckRetry configuration, while
preserving existing retry behavior for safe OrgService operations.
In `@splitsecure/services/org/grant_internal_test.go`:
- Around line 51-81: Strengthen TestGrantSchema_RequiresReplace and
TestGrantSchema_TierHasOneOfValidator by executing the configured plan modifiers
and validators instead of checking only slice lengths. Verify resource_s2r and
grantee_s2r require replacement, and verify tier accepts supported tier values
while rejecting an invalid value.
In `@splitsecure/services/org/group.go`:
- Around line 342-358: The listMemberPrincipals method must consume all
ListGroupMembers pages instead of returning only the first page. Loop while the
response provides next_cursor, requesting each subsequent page with the same
groupS2R and cursor, and append every member principal while preserving existing
empty-principal errors. Add coverage for a two-page response to verify
principals from both pages are returned.
In `@splitsecure/services/org/principal_data.go`:
- Around line 135-147: Update principalKindFromS2R to reject empty required S2R
segments, including the deployment segment and identifier segment, before
evaluating parts[2]. Preserve the existing prefix, segment-count, and
supported-kind validation, and add test cases covering malformed inputs such as
"s2r::usr:" and other empty required segments.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d6248a2c-a927-47d8-a06f-374311338599
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (34)
README.mddocs/data-sources/group.mddocs/data-sources/org_member.mddocs/data-sources/organization.mddocs/data-sources/principal.mddocs/index.mddocs/resources/grant.mddocs/resources/group.mdexamples/data-sources/splitsecure_group/data-source.tfexamples/data-sources/splitsecure_org_member/data-source.tfexamples/data-sources/splitsecure_organization/data-source.tfexamples/data-sources/splitsecure_principal/data-source.tfexamples/full/main.tfexamples/full/terraform.tfvars.exampleexamples/full/variables.tfexamples/resources/splitsecure_grant/resource.tfexamples/resources/splitsecure_group/resource.tfgo.modsplitsecure/client/client.gosplitsecure/provider/provider.gosplitsecure/services/org/configure.gosplitsecure/services/org/configure_internal_test.gosplitsecure/services/org/data_internal_test.gosplitsecure/services/org/doc.gosplitsecure/services/org/grant.gosplitsecure/services/org/grant_internal_test.gosplitsecure/services/org/group.gosplitsecure/services/org/group_data.gosplitsecure/services/org/group_internal_test.gosplitsecure/services/org/member_data.gosplitsecure/services/org/organization_data.gosplitsecure/services/org/principal_data.gosplitsecure/services/org/principal_data_internal_test.gotemplates/index.md.tmpl
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (go)
⚠️ CI failures not shown inline (2)
GitHub Actions: CI / Check Generated Docs: Add access management: grants, groups, and org data sources
Conclusion: failure
##[group]Run make check-docs
�[36;1mmake check-docs�[0m
shell: /usr/bin/bash -e {0}
env:
GOPRIVATE: github.com/splitsecure/
GOTOOLCHAIN: local
##[endgroup]
go generate ./...
go: downloading github.com/hashicorp/go-retryablehttp v0.7.8
go: downloading github.com/splitsecure/apis v0.0.0-20260717151105-8a4c7579b056
go: downloading github.com/hashicorp/terraform-plugin-log v0.10.0
go: downloading connectrpc.com/connect v1.20.0
go: downloading github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
go: downloading github.com/hashicorp/terraform-plugin-framework v1.19.0
go: downloading google.golang.org/protobuf v1.36.11
go: downloading github.com/hashicorp/go-cleanhttp v0.5.2
go: downloading github.com/hashicorp/go-hclog v1.6.3
go: downloading github.com/hashicorp/terraform-plugin-go v0.31.0
go: downloading github.com/fatih/color v1.18.0
go: downloading github.com/mattn/go-isatty v0.0.20
go: downloading github.com/vmihailenco/msgpack/v5 v5.4.1
go: downloading github.com/hashicorp/go-uuid v1.0.3
go: downloading github.com/hashicorp/go-plugin v1.7.0
go: downloading github.com/mitchellh/go-testing-interface v1.14.1
go: downloading google.golang.org/grpc v1.79.2
go: downloading github.com/mattn/go-colorable v0.1.14
go: downloading golang.org/x/sys v0.42.0
go: downloading github.com/vmihailenco/tagparser/v2 v2.0.0
go: downloading github.com/hashicorp/terraform-registry-address v0.4.0
go: downloading github.com/golang/protobuf v1.5.4
go: downloading github.com/hashicorp/yamux v0.1.2
go: downloading github.com/oklog/run v1.1.0
go: downloading golang.org/x/net v0.52.0
go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217
go: downloading github.com/hashicorp/terraform-svchost v0.1.1
go: downloading golang.org/x/text v0.36.0
go: downloading github.com/hashicorp/terraform-plugin-docs v0.25.0
go: downloading github.com/hashicorp/cli v1.1.7
go: downloading github.com/Kunde21/markdownfmt/v3 ...
GitHub Actions: CI / 2_Check Generated Docs.txt: Add access management: grants, groups, and org data sources
Conclusion: failure
##[group]Run make check-docs
�[36;1mmake check-docs�[0m
shell: /usr/bin/bash -e {0}
env:
GOPRIVATE: github.com/splitsecure/
GOTOOLCHAIN: local
##[endgroup]
go generate ./...
go: downloading github.com/hashicorp/go-retryablehttp v0.7.8
go: downloading github.com/splitsecure/apis v0.0.0-20260717151105-8a4c7579b056
go: downloading github.com/hashicorp/terraform-plugin-log v0.10.0
go: downloading connectrpc.com/connect v1.20.0
go: downloading github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
go: downloading github.com/hashicorp/terraform-plugin-framework v1.19.0
go: downloading google.golang.org/protobuf v1.36.11
go: downloading github.com/hashicorp/go-cleanhttp v0.5.2
go: downloading github.com/hashicorp/go-hclog v1.6.3
go: downloading github.com/hashicorp/terraform-plugin-go v0.31.0
go: downloading github.com/fatih/color v1.18.0
go: downloading github.com/mattn/go-isatty v0.0.20
go: downloading github.com/vmihailenco/msgpack/v5 v5.4.1
go: downloading github.com/hashicorp/go-uuid v1.0.3
go: downloading github.com/hashicorp/go-plugin v1.7.0
go: downloading github.com/mitchellh/go-testing-interface v1.14.1
go: downloading google.golang.org/grpc v1.79.2
go: downloading github.com/mattn/go-colorable v0.1.14
go: downloading golang.org/x/sys v0.42.0
go: downloading github.com/vmihailenco/tagparser/v2 v2.0.0
go: downloading github.com/hashicorp/terraform-registry-address v0.4.0
go: downloading github.com/golang/protobuf v1.5.4
go: downloading github.com/hashicorp/yamux v0.1.2
go: downloading github.com/oklog/run v1.1.0
go: downloading golang.org/x/net v0.52.0
go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217
go: downloading github.com/hashicorp/terraform-svchost v0.1.1
go: downloading golang.org/x/text v0.36.0
go: downloading github.com/hashicorp/terraform-plugin-docs v0.25.0
go: downloading github.com/hashicorp/cli v1.1.7
go: downloading github.com/Kunde21/markdownfmt/v3 ...
🧰 Additional context used
🪛 GitHub Actions: CI / 2_Check Generated Docs.txt
docs/data-sources/principal.md
[error] 1-1: Documentation content mismatch detected by check-docs (principal data source description changed).
🔇 Additional comments (29)
splitsecure/services/org/grant.go (1)
1-335: LGTM!splitsecure/services/org/grant_internal_test.go (1)
1-50: LGTM!Also applies to: 84-222
README.md (1)
9-12: LGTM!docs/data-sources/group.md (1)
1-36: LGTM!docs/data-sources/org_member.md (1)
1-34: LGTM!docs/data-sources/organization.md (1)
1-29: LGTM!examples/full/terraform.tfvars.example (1)
1-10: LGTM!examples/full/variables.tf (1)
1-15: LGTM!examples/resources/splitsecure_grant/resource.tf (1)
10-20: 🎯 Functional CorrectnessVerify standalone wiring for the resource examples.
Both examples reference Terraform objects declared outside their own files. If these snippets are presented as independently copyable examples, they will fail during planning unless the prerequisite declarations are included or the documentation clearly identifies the required companion configuration.
examples/resources/splitsecure_grant/resource.tf#L10-L20: provide or documentsplitsecure_saml2_service_provider.main,data.splitsecure_group.sre, anddata.splitsecure_organization.current.examples/resources/splitsecure_group/resource.tf#L13-L18: provide or documentdata.splitsecure_principal.aliceanddata.splitsecure_principal.ci_bot.templates/index.md.tmpl (1)
22-24: LGTM!docs/index.md (1)
42-60: LGTM!Also applies to: 79-80, 214-243
docs/resources/grant.md (1)
1-47: LGTM!docs/resources/group.md (1)
1-52: LGTM!examples/data-sources/splitsecure_group/data-source.tf (1)
1-8: LGTM!examples/data-sources/splitsecure_org_member/data-source.tf (1)
1-6: LGTM!examples/data-sources/splitsecure_organization/data-source.tf (1)
1-4: LGTM!examples/full/main.tf (1)
18-19: LGTM!Also applies to: 152-181
go.mod (1)
13-13: LGTM!splitsecure/client/client.go (1)
13-13: LGTM!Also applies to: 27-27
splitsecure/provider/provider.go (1)
15-15: LGTM!Also applies to: 113-124
splitsecure/services/org/configure.go (1)
1-30: LGTM!splitsecure/services/org/configure_internal_test.go (1)
1-32: LGTM!splitsecure/services/org/doc.go (1)
1-5: LGTM!splitsecure/services/org/organization_data.go (1)
1-98: LGTM!splitsecure/services/org/member_data.go (1)
1-131: LGTM!splitsecure/services/org/principal_data.go (1)
1-134: LGTM!splitsecure/services/org/group_data.go (1)
1-140: LGTM!splitsecure/services/org/data_internal_test.go (1)
1-100: LGTM!splitsecure/services/org/principal_data_internal_test.go (1)
1-42: LGTM!
- principalKindFromS2R rejects empty deployment / id segments. - Regenerate docs + example to the simplified data-source description (drop the stale "member directory / parse directly" wording). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
splitsecure/services/org/principal_data.go (1)
89-92: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftPass the organization ID here, not
d.client.OrgS2R(splitsecure/services/org/principal_data.go:89-92).
GetMembersByEmailRequest.Base.OrganizationIdexpects the org ID;d.client.OrgS2Ris the configured org S2R URI. Thread the resolved org ID into this path before callingGetMembersByEmail, or principal lookups will fail.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@splitsecure/services/org/principal_data.go` around lines 89 - 92, Update the principal lookup flow around GetMembersByEmail so GetMembersByEmailRequest.Base.OrganizationId receives the resolved organization ID rather than d.client.OrgS2R, which is the configured S2R URI. Thread that resolved ID into this path before calling d.client.OrgService.GetMembersByEmail, preserving the existing email lookup behavior.Source: Linked repositories
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@splitsecure/services/org/principal_data.go`:
- Around line 89-92: Update the principal lookup flow around GetMembersByEmail
so GetMembersByEmailRequest.Base.OrganizationId receives the resolved
organization ID rather than d.client.OrgS2R, which is the configured S2R URI.
Thread that resolved ID into this path before calling
d.client.OrgService.GetMembersByEmail, preserving the existing email lookup
behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c9c0a400-a029-4f31-9673-af8a0eef415d
📒 Files selected for processing (4)
docs/data-sources/principal.mdexamples/data-sources/splitsecure_principal/data-source.tfsplitsecure/services/org/principal_data.gosplitsecure/services/org/principal_data_internal_test.go
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
splitsecure/apis(auto-detected)
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (go)
🧰 Additional context used
🔀 Multi-repo context splitsecure/apis
Linked repositories findings
splitsecure/apis
- Org scoping differs across RPCs. Grant requests explicitly require
org_s2r(put_grant.proto:8-13,get_grant.proto:7-11,delete_grant.proto:5-9), whileGetMembersByEmailRequestrequiresbase.organization_id(get_members_by_email.proto:19-27). The provider’s principal data source should ensure it sends the organization ID, not the configuredorg_s2r.[::splitsecure/apis::] - Group-member listing is cursor-paginated.
ListGroupMembersRequestexposeslimitandcursor, and the response returnsnext_cursor(list_group_members.proto:7-15). The provider’s group read/reconciliation logic must follownext_cursorto avoid managing only the first page of membership.[::splitsecure/apis::] - Group mutations accept only user/service-account principals.
AddGroupMembersRequestexplicitly rejects other S2R kinds (add_group_members.proto:5-9), consistent with the provider’s documentedmembersrestriction.[::splitsecure/apis::] - Everyone is a system group and is intentionally excluded from group listings. Its S2R must come from
Organization.everyone_group_s2r;ListGroupMembersrejects it (orgsvc_service.proto:35-40,organization_resource.proto:8-11). This matches the new organization data-source documentation and example usage.[::splitsecure/apis::] - Grant mutations require edit authorization.
PutGrant/delete operations require the caller to hold edit tier on the resource, with org owners/admins implicit (orgsvc_service.proto:50-56). The provider’s retry handling for permission races does not replace the required authorization.[::splitsecure/apis::]
🔇 Additional comments (4)
splitsecure/services/org/principal_data.go (1)
135-148: LGTM!splitsecure/services/org/principal_data_internal_test.go (1)
18-19: LGTM!docs/data-sources/principal.md (1)
5-41: LGTM!examples/data-sources/splitsecure_principal/data-source.tf (1)
1-12: LGTM!
- client: give OrgService a non-retrying HTTP client so a lost response never replays a non-idempotent mutation (CreateGroup / UpdateGroup / DeleteGroup / PutGrant / DeleteGrant); keep retries for the enclave flow. - group: listMemberPrincipals now consumes every ListGroupMembers page via next_cursor (was truncated at the first page) + a two-page test. - grant schema tests: execute the tier validators (accept real tiers, reject others) and check the key attributes carry requires-replace semantics. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d4f6966 to
a9e8490
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@splitsecure/services/org/grant_internal_test.go`:
- Around line 87-119: Update the local validate function in
TestGrantSchema_TierValidatorAcceptsTiers by inserting a blank line immediately
before return resp.Diagnostics to satisfy the nlreturn linter.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9aaa103f-9e48-4096-ba06-3c8814c87782
📒 Files selected for processing (4)
splitsecure/client/client.gosplitsecure/services/org/grant_internal_test.gosplitsecure/services/org/group.gosplitsecure/services/org/group_internal_test.go
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
splitsecure/apis(auto-detected)
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (go)
🧰 Additional context used
🪛 GitHub Actions: CI / 1_Lint.txt
splitsecure/services/org/grant_internal_test.go
[error] 108-108: golangci-lint: nlreturn violation. 'return' statement missing a blank line before it.
🪛 GitHub Actions: CI / Lint
splitsecure/services/org/grant_internal_test.go
[error] 108-108: golangci-lint: (nlreturn) return statement must be preceded by a blank line.
🪛 GitHub Check: Lint
splitsecure/services/org/grant_internal_test.go
[failure] 108-108:
return with no blank line before (nlreturn)
🔀 Multi-repo context splitsecure/apis
Linked repositories findings
splitsecure/apis
- Org-scoped grant RPCs require
org_s2r, while member lookup usesbase.organization_id; callers must not substitute the provider’s organization S2R for the latter.[::splitsecure/apis::] - Group-member listing is cursor-paginated via
limit,cursor, andnext_cursor; provider reads must consume all pages.[::splitsecure/apis::] - Group mutations accept only user/service-account principals, matching the provider’s documented membership restriction.
[::splitsecure/apis::] - The Everyone group is system-managed and excluded from normal group listings; its S2R comes from
Organization.everyone_group_s2r.[::splitsecure/apis::] - Grant mutations require edit authorization on the resource, with org owners/admins implicit; retry logic does not replace authorization.
[::splitsecure/apis::]
🔇 Additional comments (4)
splitsecure/services/org/group.go (1)
343-362: LGTM!splitsecure/services/org/group_internal_test.go (1)
7-7: LGTM!Also applies to: 36-36, 70-86, 467-484
splitsecure/client/client.go (1)
37-64: LGTM!splitsecure/services/org/grant_internal_test.go (1)
49-85: LGTM!Also applies to: 121-259
Re-pin github.com/splitsecure/apis from the 8a4c757 pseudo-version to the merged apis-main tip 1efd2ff, so the provider sits on the same apis-main commit as priv. No source changes — GetMembersByEmail is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the full-directory ListMembers pull + client-side EqualFold scan with the server-side GetMembersByEmail lookup built for this. Besides the efficiency win (one indexed keyed lookup vs. streaming the whole member directory on every plan), this fixes three correctness gaps: - pagination: the old path read only the first ListMembers page, so a member past page one resolved as "no org member"; - canonicalization: matching now happens server-side (+tag/IDNA/etc.) instead of a naive case-insensitive compare; - service accounts: SA emails now resolve (saemail), which an EqualFold scan over Members could never do. matchMemberByEmail -> singleMember: the client now only extracts the one member from the per-email Result (0 = not found, >1 = ambiguous); the matching itself is the server's job. Test migrated to the narrowed contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@splitsecure/services/org/data_internal_test.go`:
- Around line 30-33: Reformat the overlong table literals in the test cases
“single member resolves” and “no matching result returns error naming the email”
into multiple lines so each line stays within the configured 200-character
limit, without changing their values or assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 548bacc2-6e61-42e5-966b-a41b170ea38e
📒 Files selected for processing (2)
splitsecure/services/org/data_internal_test.gosplitsecure/services/org/member_data.go
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
splitsecure/apis(auto-detected)
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (go)
🧰 Additional context used
🪛 GitHub Actions: CI / 0_Lint.txt
splitsecure/services/org/data_internal_test.go
[error] 31-31: golangci-lint: The line is 220 characters long, which exceeds the maximum of 200 characters. (lll)
🪛 GitHub Actions: CI / Lint
splitsecure/services/org/data_internal_test.go
[error] 31-31: golangci-lint (lll): The line is 220 characters long, which exceeds the maximum of 200 characters.
🪛 GitHub Check: Lint
splitsecure/services/org/data_internal_test.go
[failure] 33-33:
The line is 213 characters long, which exceeds the maximum of 200 characters. (lll)
[failure] 31-31:
The line is 220 characters long, which exceeds the maximum of 200 characters. (lll)
🔀 Multi-repo context
Linked repositories findings
No additional cross-repository context beyond the previously identified API contract findings was necessary.
🔇 Additional comments (1)
splitsecure/services/org/member_data.go (1)
116-124: 🎯 Functional CorrectnessDrop this finding.
singleMemberintentionally matches the echoed request email, and the tests codify that contract.> Likely an incorrect or invalid review comment.
Return the per-email Result slice from a oneResult helper so the table-driven cases fit under the 200-char line limit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Adds access-management resources to the provider so a Terraform config can grant users, service accounts, and groups access to SplitSecure resources — closing the gap where a resource created via Terraform was invisible to everyone but its creator until an admin fixed it up by hand. New resources
splitsecure_grantandsplitsecure_group, plus data sources to resolve principals and the org's directory.Stacked on splitsecure/apis#14 and priv#1068 (merge those first).
go.modcurrently carries a dev-onlyreplace github.com/splitsecure/apis => ../apis; before this is un-drafted the replace is dropped and the require is pinned to the merged apis version. CI is red until then.Provider
splitsecure_grant— per-resource grant(resource, grantee) → view|use|edit.PutGrantupsert semantics, so changingtierupdates in place; changing resource/grantee replaces. Create retriesPermissionDeniedbriefly to absorb the server-side creator-grant write race after a resource's create-proposal lands. Import byresource_s2r,grantee_s2r.splitsecure_group— locally-managed principal group with an authoritativemembersset. Refuses SCIM/system groups. Group mutations require the provider's service account to hold the org admin role (grants alone work with the default member role, via the creator grant).splitsecure_organization(incl. the "Everyone" group S2R for org-wide grants),splitsecure_org_member(user S2R by email),splitsecure_group(existing group by name, e.g. SCIM-synced).Example usage
Terraform's dependency graph orders each grant after the resource it references (whose create blocks through voter approval), and destroy deletes grants before the resource. Tiers control who can see and administer a resource; resource mutations remain proposal/voter-gated regardless of tier.
Self-review
A workflow-backed review (xhigh) surfaced 9 findings; the load-bearing ones are fixed in this branch:
NotFound— matchesDeleteGroup/DeleteGrant; an already-gone principal no longer wedges apply.upsertGrant(Create/Update differ only by the auth retry); a package-localclientFromProviderDatafor all five Configure methods.UseStateForUnknownguards in group Update.clientFromProviderData, and member-removalNotFound-tolerance plus the non-NotFoundfailure path (via a minimal fake OrgService client).Findings intentionally not actioned: the group
Readnon-LOCAL guard (a group'ssourceis immutable server-side —UpdateGrouponly writes name, SCIM groups are a separate store — so it's unreachable;terraform state rmremains the escape hatch), and empty-everyone_group_s2r/ unset-CreateGroup-sourcehandling (old orgs are out of scope; the server echoingsourceis the contract).Test plan
replace, pin the apis require,go build/go test/golangci-lint,make check-docs.go build ./...,go test ./...(incl. new grant/group unit tests),golangci-lint run(only finding is the temporary localreplace).