nhi: GitLab class-B — PAT/deploy-token/service-account syncers (Phase-1, S-scope)#90
Open
c1-squire-dev[bot] wants to merge 6 commits into
Open
nhi: GitLab class-B — PAT/deploy-token/service-account syncers (Phase-1, S-scope)#90c1-squire-dev[bot] wants to merge 6 commits into
c1-squire-dev[bot] wants to merge 6 commits into
Conversation
Bumps baton-sdk v0.3.35 -> v0.13.0 to pick up the NHI Phase-1 spine traits added in baton-sdk#902 (SecretTrait.credential_type + WithSecretType/WithSecretDetail builders), required to emit K1 credential-type classification on the new token syncers. The only forced source change is crypto.GenerateRandomPassword, whose argument type moved from CredentialOptions_RandomPassword to LocalCredentialOptions_RandomPassword. Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
…se-1, S-scope) Adds three new NHI resource-type syncers to the GitLab connector (pqprime NHI Phase-1, RFC §5.8.1 — class B): - personal_access_token (K1 / STATIC_SECRET, axis-2 gitlab.token.pat) GET /personal_access_tokens; owner user_id -> SecretTrait identity back-reference. - deploy_token (K1 / STATIC_SECRET, axis-2 gitlab.token.deploy) GET /deploy_tokens; not tied to a user, so no identity back-reference. - service_account (K2 / SERVICE) GET /service_accounts (self-managed) and per-top-level-group GET /groups/:id/service_accounts (GitLab.com), emitted as TRAIT_USER with account_type SERVICE. Credential type is emitted positively (STATIC_SECRET) only; unknown classification is left UNSPECIFIED per RFC §2.6. No V1Identifier is set. Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
baton-sdk v0.11.0+ (the NHI spine traits) declares go 1.25.2, which propagates to this module's go.mod. The CI workflows were pinned to 1.23.x (matching the previously-vendored v0.3.35) and must move to 1.25.x or go-test/go-lint fail on the go directive. Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Contributor
Connector PR Review: nhi: GitLab class-B — PAT/deploy-token/service-account syncers (Phase-1, S-scope)Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0 Review SummaryThe new commit adds handling for HTTP 401 Unauthorized responses alongside the existing 403 Forbidden handling. A new Security IssuesNone found. Correctness IssuesNone found. SuggestionsNone. |
Two changes forced by the baton-sdk v0.13.0 bump:
- The account-manager interface now takes *v2.LocalCredentialOptions
instead of *v2.CredentialOptions; userBuilder's CreateAccount/helpers
are migrated so the connector no longer trips the SDK's "old account
manager interface" startup guard (caught by test-cloud-version).
- golangci-lint (CI) flags repeated string literals (goconst); extract
the profile/account-schema field keys (name/email/username) and the
keyset sort direction ("asc") into constants.
Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
The instance PAT, deploy-token and service-account endpoints require an admin (or group-owner) token. A non-admin token returns 403, which previously failed the entire sync. Handle PermissionDenied/403 the same way member listing does (handlePermissionError): log and skip the resource type, leaving the rest of the sync intact. Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
GitLab returns 401 (not 403) for group/project access-token and service-account endpoints when the token lacks the required role on a specific resource. The token is valid (Validate exercises it), so treat 401 like 403 in handlePermissionError: log and skip the resource instead of aborting the sync. Adds a client.ErrUnauthorized sentinel + 401 case in CheckResponse. Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Preview: C1
nhi: GitLab class-B — PAT / deploy-token / service-account syncers (Phase-1, S-scope)
Part of the pqprime NHI program (RFC
plans/nhi/rfc/rfc-v6.md). This is the S-scope half of the GitLab class-B work — the single highest-yield connector gap (5 new NHI resource types). The M-scope half (project/group access tokens) is stacked on top in a follow-up PR.Build-location decision (gate)
The GitLab connector has historically existed in two places. I resolved where new syncer code must land today:
ConductorOne/baton-gitlab(this repo) is the live fleet / lambda deploy source: actively maintained (latest commit yesterday, viabaton-admin), released (v0.0.31), vendorsaws-lambda-go(deployed as a lambda executor), built on the Baton SDK. → build here.ductone/c1pkg/connector/gitlabis the legacy v1 implementation — c1 PR #12143 literally calls it "the v1 Gitlab connector". It is not the deploy source for new connector work.Per the program's decision rule ("if an upstream
baton-gitlabexists and is the deploy source → build there"), all new syncers land in this repo. This is connector source code, not a vendor bump of a connector inside c1.What this PR adds (RFC §5.8.1, class B)
personal_access_tokengitlab.token.patGET /personal_access_tokens— admin lists all instance PATs, else self; metadata only, secret never returned on listdeploy_tokengitlab.token.deployGET /deploy_tokens— admin/instance; metadata only, secret only on createservice_accountGET /service_accounts(self-managed) +GET /groups/:id/service_accounts(GitLab.com, 17.1+)SecretTraitstampedcredential_type = STATIC_SECRETplus the axis-2credential_detail. Identity back-ref: PATs exposeuser_id, so the owning user is set asSecretTrait.identity_id(K1↔K2 link). Deploy tokens are not tied to a user, so no back-ref is emitted (back-refs only where the API gives the owner).TRAIT_USERwithaccount_type = SERVICE. On GitLab.com the instance endpoint is unavailable, so the builder fans out per top-level group via aChildResourceTypeannotation (mirrors the existing user-sync dual path).RFC rule compliance
credential_typeis only ever set toSTATIC_SECRET(the resource is the credential); nothing coerces a wrong concrete value.V1Identifieris set on any new resource (v1→v2 migration-only; precedentbaton-temporalcloud#82r3380796810).<platform>.<object>.<purpose>convention (§2.8).baton-sdk bump (required dependency)
Emitting
credential_typeneedsSecretTrait.credential_type+WithSecretType/WithSecretDetail, added upstream in baton-sdk#902 ("NHI Phase-1 spine traits" — PR-1 of this program). This repo vendored the stalev0.3.35, so the first commit bumps baton-sdkv0.3.35→v0.13.0and re-vendors. The only forced source change iscrypto.GenerateRandomPassword, whose arg type moved toLocalCredentialOptions_RandomPassword. (Largevendor/diff is the SDK bump; review the second commit for the feature.)Testing
go build ./...,go test ./...,golangci-lint run,gofmt— all green.account_type = SERVICE(service account).🤖 Built with pqprime
Exposed endpoints
🏰 Squire environment: sleepy-dolphin-46579
Task: d94ceb36-4399-49c3-a3fd-977c87ce323b