[CXH-2292] - Migrate to ConnectorBuilderV2 and gate cross-resource grants - Grafana Connector - #81
Conversation
… grants Carry C1's resource-type selection into sync so cross-resource grants are emitted only when their target entitlement types are scheduled. Co-authored-by: Cursor <cursoragent@cursor.com>
Connector PR Review: [CXH-2292] - Migrate to ConnectorBuilderV2 and gate cross-resource grants - Grafana ConnectorBlocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0 Review SummaryThe full PR diff was scanned for security and correctness; the new commit ( Security IssuesNone found. Correctness IssuesNone found. Suggestions
Prompt for AI agents |
Keep the org-excluded resource type as a strict extension of the advertised service account type when adding the stronger sync skip annotation. Co-authored-by: Cursor <cursoragent@cursor.com>
sergiocorral-conductorone
left a comment
There was a problem hiding this comment.
Automated review
Keep restored grant cursors subject to the current resource-type selection and make optional V2 entitlement interfaces fail at compile time if their signatures drift. Co-authored-by: Cursor <cursoragent@cursor.com>
Let the SDK scheduler enforce service-account grant skips through one runtime annotation, avoiding redundant guards and overlapping skip instructions. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Followed up on the deep-code-review nits from earlier — all addressed in af44697 / 9cfba42 (switch→if/else in |
| return true | ||
| } | ||
|
|
||
| return g.connectorOpts.WillSyncResourceType(resourceTypeID) |
There was a problem hiding this comment.
Did some due-diligence on the SDK side before this gets approved (traced WillSyncResourceType, SkipEntitlementsAndGrants gating through the sequential + parallel syncer, and every site that populates SyncResourceTypeIDs). The core mechanism this PR relies on holds up — the resource-type-level SkipEntitlementsAndGrants annotation is checked by the syncer before it ever calls into the connector's Grants(), in both sync paths, independent of the coarse whole-sync skip flag.
One thing worth flagging though, not really actionable in this PR but worth being aware of: g.connectorOpts here is fixed at connector-process boot (populated from local CLI flags in daemon/service/gRPC mode — pkg/cli/commands.go:464/:670 in the vendored SDK). Unlike lambda mode (which reloads on a config-version header change) and unlike the SDK's own separate per-task sdkSync.WithSyncResourceTypes filter (pkg/tasks/c1api/full_sync.go:245-250), there's no per-task refresh here. So if a tenant changes their resource-type selection in the C1 UI without the connector daemon restarting, the SDK's own sync-type filter would correctly pick up the new selection, but willSyncResourceType here — and therefore the SA-org-grant / team-role-grant gating — could still be acting on the stale selection from boot time until a restart happens.
Might be worth a quick check with whoever owns the deployment story: does C1's orchestration guarantee a restart when a tenant's resource-type selection changes for a long-running (non-lambda) connector? If yes, this is a non-issue. If not, it's a pre-existing SDK/deployment-model gap this PR doesn't introduce and can't really fix on its own, but it's the sort of thing worth a follow-up ticket.
Description
This migrates baton-grafana to the SDK V2 connector interfaces required by
config.RunConnector. It also carries C1's selected resource types into the connector so cross-resource grants are emitted only when their target entitlement type is part of the sync.The migration preserves the existing resource IDs and full-sync grant surface. Account provisioning and entitlement provisioning behavior are unchanged.
Intent
CXH-2292 acceptance criteria:
RunConnector+ConnectorBuilderV2.user,org,team,role,service_account) matches pre-migration IDs and grants.orglists service accounts and emits no service-account-to-org grants.orgstill emits immutable service-account org-role grants.rolelists teams and emits membership grants without calling/api/access-control/teams/{id}/roles.rolestill emits team-to-role grants.Fixes CXH-2292
Sync:
user) — migrated toResourceSyncerV2; resources and grants are unchanged.org) — migrated toResourceSyncerV2; resources, entitlements, and grants are unchanged.team) — migrated toResourceSyncerV2; membership grants are always emitted, while the team-role page is scheduled only whenroleis selected.role) — migrated toResourceSyncerV2; resources and entitlements are unchanged.service_account) — migrated toResourceSyncerV2; accounts remain listed whenorgis excluded, while org entitlements and grants are skipped.Provisioning:
Auth:
Authentication is unchanged: API tokens continue to select Grafana Cloud mode, while username/password credentials select self-hosted mode.
Architecture highlights:
config.RunConnectorwithConnectorBuilderV2and V2 resource syncers.cli.ConnectorOpts.SkipEntitlementsAndGrants, leaving the shared type unchanged.SyncOpResultsnil when there is no pagination or annotation data to return.Verification:
GOFLAGS=-mod=vendor go build ./...GOFLAGS=-mod=vendor golangci-lint run ./...GOFLAGS=-mod=vendor go test ./...org, service accounts remain present and their org grants drop to zero.role, team membership remains present and the team-role endpoint receives zero calls.Useful links: