Skip to content

Containerize baton-jamf connector#16

Merged
laurenleach merged 2 commits intomainfrom
containerize-baton-jamf
Mar 20, 2026
Merged

Containerize baton-jamf connector#16
laurenleach merged 2 commits intomainfrom
containerize-baton-jamf

Conversation

@laurenleach
Copy link
Copy Markdown
Contributor

@laurenleach laurenleach commented Jan 29, 2026

Containerizes the connector following baton-databricks#35 and baton-contentful#48.

Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com

Summary by CodeRabbit

  • Chores
    • Updated Go toolchain to 1.25.2 and refreshed core dependencies for security, stability, and performance.
  • New Features
    • Configuration UI/metadata improved: clearer display names, secret marking for credentials, help and icon links.
  • Refactor
    • Unified synchronization APIs and upgraded syncer interfaces for more consistent and extensible resource sync behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@laurenleach laurenleach requested a review from a team January 29, 2026 23:16
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 29, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Walkthrough

Updated Go toolchain and module graph; added a generated Jamf config with reflection-based getters; refactored connector constructor and multiple resource-type APIs to use rs.SyncOpAttrs/*rs.SyncOpResults in place of pagination tokens and annotations.

Changes

Cohort / File(s) Summary
Dependency Upgrade
go.mod
Bumped Go toolchain to 1.25.2 and upgraded github.com/conductorone/baton-sdk (v0.2.46 → v0.7.10) with extensive transitive dependency updates (gRPC, AWS SDK v2 components, grpc-gateway, OpenTelemetry, x/* packages, etc.).
Configuration Infrastructure
pkg/config/conf.gen.go, pkg/config/schema.go
Adds generated Jamf struct with mapstructure tags and reflection-based getters (GetString, GetInt, GetBool, GetStringSlice, GetStringMap). Exports ConfigurationFields, FieldRelationships, and initializes public Config with display/help metadata and go:generate directive.
Connector Core
pkg/connector/connector.go
Constructor New signature changed to accept *cfg.Jamf and *cli.ConnectorOpts, now returning connectorbuilder.ConnectorBuilderV2, []connectorbuilder.Opt, error; error returns adjusted to (nil, nil, err). ResourceSyncers now returns []connectorbuilder.ResourceSyncerV2 and includes additional syncers.
Resource Type APIs
pkg/connector/user.go, pkg/connector/userAccount.go, pkg/connector/userGroup.go, pkg/connector/group.go, pkg/connector/role.go, pkg/connector/site.go
Unified API change: List, Entitlements, and Grants now accept rs.SyncOpAttrs (replacing pagination.Token) and return *rs.SyncOpResults (replacing string/annotations). Error-return patterns and imports updated accordingly across all resource types.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through modules, shiny and spry,
A Jamf with reflectors caught my eye,
Tokens traded for SyncOpAttrs' tune,
Sync results hum beneath the moon,
A tiny rabbit cheers this code renewal 🥕✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'Containerize baton-jamf connector' is vague and does not accurately reflect the actual changes, which are primarily SDK API migration updates (pagination/annotations to SyncOpAttrs), configuration refactoring, and code generation—not containerization. Update the title to reflect the main changes, such as 'Update to Baton SDK v0.7.10 with ResourceSyncerV2 and SyncOpAttrs migration' or 'Migrate resource syncers to v2 API and update dependency versions'.
Docstring Coverage ⚠️ Warning Docstring coverage is 46.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch containerize-baton-jamf

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/connector/group.go (1)

85-112: Build failure: Return statements not migrated to new API.

The pipeline failure at line 90 is caused by return statements that still use the old 4-value return pattern (nil, "", nil, err) instead of the new 3-value pattern (nil, nil, err).

Lines 90 and 105 need to be updated to match the new Grants method signature.

🐛 Proposed fix for the return statements
 	groupId, err := strconv.Atoi(resource.Id.Resource)
 	if err != nil {
-		return nil, "", nil, err
+		return nil, nil, err
 	}

 	// HACK: the endpoint to get group details returns a members list, but it comes back empty
 	// sometimes when it shouldn't. This is a bug in the Jamf API.
 	// This is a workaround to get the members list as of 22/05/2025 and is not 100% reliable.
 	// but from what's i've seen, it will return the members list after 2-3 tries. (if there are
 	// any members at all in that group)
 	// https://developer.jamf.com/jamf-pro/reference/findgroupsbyid
 	// if this endpoint becomes reliable again, we can remove this for loop
 	var group *jamf.Group
 	count := 0
 	for count < 5 {
 		group, err = g.client.GetGroupDetails(ctx, groupId)
 		if err != nil {
-			return nil, "", nil, err
+			return nil, nil, err
 		}
 		if len(group.Members) > 0 {
 			break
 		}
 		count++
 		time.Sleep(time.Second)
 	}
🤖 Fix all issues with AI agents
In `@go.mod`:
- Around line 104-107: Update the vulnerable module versions in go.mod by
bumping golang.org/x/crypto to at least v0.35.0 (preferably latest v0.47.0) and
golang.org/x/oauth2 to at least v0.27.0 (preferably latest v0.34.0); then run
the go tooling to apply the changes (go get golang.org/x/crypto@v0.47.0
golang.org/x/oauth2@v0.34.0), run go mod tidy to refresh go.sum, and run the
test suite/build to ensure no breakages; also check for any replace directives
or indirect consumers that might pin older versions and update them accordingly.
🧹 Nitpick comments (1)
pkg/connector/site.go (1)

25-36: Unused parentResourceID parameter.

The parentResourceID parameter is declared but never used in the siteResource function. Consider either using it or removing it if not needed.

♻️ Suggested fix
-func siteResource(site *jamf.Site, parentResourceID *v2.ResourceId) (*v2.Resource, error) {
+func siteResource(site *jamf.Site) (*v2.Resource, error) {

Note: If you remove the parameter, you'll also need to update the call site at line 47 to siteResource(&siteCopy).

Comment thread go.mod Outdated
Comment on lines +104 to +107
golang.org/x/crypto v0.34.0 // indirect
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if crypto/ssh or oauth2 packages are used directly or transitively
echo "=== Checking for ssh usage ==="
rg 'golang.org/x/crypto/ssh' --type go -l || echo "No direct ssh imports found"

echo ""
echo "=== Checking for oauth2 usage ==="
rg 'golang.org/x/oauth2' --type go -l || echo "No direct oauth2 imports found"

echo ""
echo "=== Checking go.sum for affected packages ==="
grep -E 'golang.org/x/(crypto|oauth2)' go.sum | head -20

echo ""
echo "=== Checking baton-sdk dependency for transitive usage ==="
# Look for what baton-sdk depends on
grep -A 5 -B 5 'baton-sdk' go.mod

Repository: ConductorOne/baton-jamf

Length of output: 2815


🌐 Web query:

latest patched versions golang.org/x/crypto golang.org/x/oauth2 2025 vulnerabilities security

💡 Result:

golang.org/x/oauth2 (2025 security vuln + latest)

  • 2025 vuln: CVE-2025-22868 / GO-2025-3488 (unexpected memory consumption in golang.org/x/oauth2/jws) — fixed in v0.27.0 (tagged Feb 24, 2025). [1] [2]
  • Latest module version (as of 2026-01-29): v0.34.0 (Dec 1, 2025). [3]

Action: use golang.org/x/oauth2@v0.27.0 or newer (prefer latest):

go get golang.org/x/oauth2@v0.34.0

golang.org/x/crypto (2025 security vuln + latest)

  • 2025 vuln: CVE-2025-22869 / GO-2025-3487 (DoS in golang.org/x/crypto/ssh) — fixed in v0.35.0 (tagged Feb 24, 2025). [4] [5]
  • Additional 2025 ssh/agent vulns appear on pkg.go.dev for versions <= v0.44.0, and are no longer flagged starting v0.45.0. [6]
  • Latest module version (as of 2026-01-29): v0.47.0 (Jan 12, 2026). [6]

Action: use golang.org/x/crypto@v0.35.0 or newer (prefer latest):

go get golang.org/x/crypto@v0.47.0

Sources

[1] https://groups.google.com/g/golang-announce/c/wImnF7NFhJE
[2] https://pkg.go.dev/vuln/GO-2025-3488
[3] https://pkg.go.dev/golang.org/x/oauth2?tab=versions
[4] https://groups.google.com/g/golang-announce/c/qN_GDasRQSA
[5] https://pkg.go.dev/vuln/GO-2025-3487
[6] https://pkg.go.dev/golang.org/x/crypto?tab=versions


Upgrade golang.org/x/crypto and golang.org/x/oauth2 to patched versions immediately.

Both packages contain confirmed 2025 security vulnerabilities and are actively used in the codebase:

  1. golang.org/x/crypto v0.34.0 (Line 104):

    • CVE-2025-22869 / GO-2025-3487: DoS vulnerability in SSH package
    • Additional SSH/agent vulnerabilities flagged for versions ≤ v0.44.0
    • Patched in: v0.35.0 (Feb 24, 2025) | Latest: v0.47.0 (Jan 12, 2026)
    • Current usage: SSH/agent code is actively used via baton-sdk's JWK providers and age package
  2. golang.org/x/oauth2 v0.26.0 (Line 107):

    • CVE-2025-22868 / GO-2025-3488: Unexpected memory consumption during token parsing
    • Patched in: v0.27.0 (Feb 24, 2025) | Latest: v0.34.0 (Dec 1, 2025)
    • Current usage: OAuth2 is actively used throughout baton-sdk and dependency chain

Upgrade to at least the patched versions, or preferably the latest stable releases available.

🧰 Tools
🪛 OSV Scanner (2.3.2)

[HIGH] 104-104: golang.org/x/crypto 0.34.0: Potential denial of service in golang.org/x/crypto

(GO-2025-3487)


[HIGH] 104-104: golang.org/x/crypto 0.34.0: Potential denial of service in golang.org/x/crypto/ssh/agent

(GO-2025-4116)


[HIGH] 104-104: golang.org/x/crypto 0.34.0: Unbounded memory consumption in golang.org/x/crypto/ssh

(GO-2025-4134)


[HIGH] 104-104: golang.org/x/crypto 0.34.0: Malformed constraint may cause denial of service in golang.org/x/crypto/ssh/agent

(GO-2025-4135)


[HIGH] 104-104: golang.org/x/crypto 0.34.0: golang.org/x/crypto/ssh/agent vulnerable to panic if message is malformed due to out of bounds read

(GHSA-f6x5-jh6r-wrfv)


[HIGH] 104-104: golang.org/x/crypto 0.34.0: golang.org/x/crypto Vulnerable to Denial of Service (DoS) via Slow or Incomplete Key Exchange

(GHSA-hcg3-q754-cr77)


[HIGH] 104-104: golang.org/x/crypto 0.34.0: golang.org/x/crypto/ssh allows an attacker to cause unbounded memory consumption

(GHSA-j5w8-q4qc-rx2x)


[HIGH] 107-107: golang.org/x/oauth2 0.26.0: Unexpected memory consumption during token parsing in golang.org/x/oauth2

(GO-2025-3488)


[HIGH] 107-107: golang.org/x/oauth2 0.26.0: golang.org/x/oauth2 Improper Validation of Syntactic Correctness of Input vulnerability

(GHSA-6v2p-p543-phr9)

🤖 Prompt for AI Agents
In `@go.mod` around lines 104 - 107, Update the vulnerable module versions in
go.mod by bumping golang.org/x/crypto to at least v0.35.0 (preferably latest
v0.47.0) and golang.org/x/oauth2 to at least v0.27.0 (preferably latest
v0.34.0); then run the go tooling to apply the changes (go get
golang.org/x/crypto@v0.47.0 golang.org/x/oauth2@v0.34.0), run go mod tidy to
refresh go.sum, and run the test suite/build to ensure no breakages; also check
for any replace directives or indirect consumers that might pin older versions
and update them accordingly.

@laurenleach laurenleach marked this pull request as draft February 3, 2026 20:08
@laurenleach laurenleach force-pushed the containerize-baton-jamf branch from 736975f to 324fb3b Compare March 20, 2026 22:06
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 20, 2026

Claude finished @laurenleach's task in 2m 22s —— View job


PR Review: Containerize baton-jamf connector

  • Gather context and diff
  • Review connector source changes
  • Review config and build changes
  • Review dependency updates
  • Post final review

Overview

This PR migrates the connector to the new SDK v2 API (baton-sdk v0.2.46 → v0.8.14), adds generated config infrastructure, updates CI workflows, and bumps the Go toolchain to 1.25.2. The core changes look correct — the ResourceSyncerV2 interface migration is properly applied across all builders.

Issues

1. siteResource unused parameter — pkg/connector/site.go:25

The parentResourceID parameter is accepted but never used in the function body:

func siteResource(site *jamf.Site, parentResourceID *v2.ResourceId) (*v2.Resource, error) {
    ret, err := rs.NewResource(
        site.Name,
        resourceTypeSite,
        site.ID,
    )

This is likely a bug — parentResourceID should probably be passed via rs.WithParentResourceID(parentResourceID) like all the other resource builders do (see groupResource, userResource, userGroupResource, roleResource, userAccountResource). Without it, site resources won't have parent relationships set.

Fix this →

2. Retry loop without context cancellation check — pkg/connector/group.go:100-112

The retry loop for the flaky Jamf API uses time.Sleep(time.Second) without checking ctx.Done():

for count < 5 {
    group, err = g.client.GetGroupDetails(ctx, groupId)
    if err != nil {
        return nil, nil, err
    }
    if len(group.Members) > 0 {
        break
    }
    count++
    time.Sleep(time.Second)
}

If the context is cancelled, this will block for up to 5 seconds instead of returning promptly. Consider using select with ctx.Done() or time.After. (This is a pre-existing issue, not introduced by this PR, so low priority.)

Observations (Non-blocking)

  • spf13/viper moved from direct to indirect dependencyviper was previously in the require block directly but is now pulled in transitively through the SDK. This is correct behavior.
  • Security vulnerabilities flagged by CodeRabbit (golang.org/x/crypto v0.44.0, golang.org/x/oauth2 v0.32.0) — these are indirect dependencies pinned by baton-sdk v0.8.14. The versions in this PR are significantly newer than what CodeRabbit flagged (which was v0.34.0 / v0.26.0 from an earlier push). The current golang.org/x/crypto v0.44.0 addresses CVE-2025-22869 (fixed in v0.35.0) and golang.org/x/oauth2 v0.32.0 addresses CVE-2025-22868 (fixed in v0.27.0). These are now patched.
  • Generated code (conf.gen.go) uses panic("wrong type") in getter methods — this is standard for the baton config generator and is acceptable since type mismatches indicate programming errors.
  • main.go is clean and minimal — good use of the new config.RunConnector pattern with ConnectorBuilderV2.
  • Makefile properly handles config code generation as a build dependency.
  • CI workflow improvements (setup-go v5, go-version-file instead of hardcoded version, push-to-main trigger) are good.

Verdict

The SDK migration is correctly applied across all 6 resource builders. The only actionable issue is the unused parentResourceID in siteResource which appears to be a bug (missing WithParentResourceID option). Everything else looks good.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 20, 2026

Claude finished @laurenleach's task in 2m 2s —— View job


PR Review: Containerize baton-jamf connector

  • Gather context and diff
  • Review connector source changes
  • Review config and build changes
  • Review dependency updates
  • Post final review

Overview

This PR migrates the connector from baton-sdk v0.2.46 to v0.8.14, adopting the ResourceSyncerV2 / ConnectorBuilderV2 interfaces. It also adds generated config infrastructure (conf.gen.go), updates CI workflows, and bumps the Go toolchain to 1.25.2. The SDK migration is correctly applied across all 6 resource builders.

Issues

1. Bug: parentResourceID unused in siteResourcepkg/connector/site.go:25-30

The parentResourceID parameter is accepted but never passed to rs.NewResource:

func siteResource(site *jamf.Site, parentResourceID *v2.ResourceId) (*v2.Resource, error) {
    ret, err := rs.NewResource(
        site.Name,
        resourceTypeSite,
        site.ID,
    )

Every other resource builder (groupResource, userResource, userGroupResource, roleResource, userAccountResource) passes rs.WithParentResourceID(parentResourceID) to its NewResource/NewGroupResource/etc. call. Without this, site resources won't have parent relationships set.

Fix: Add rs.WithParentResourceID(parentResourceID) as an option to the rs.NewResource call.

Fix this →

2. Pre-existing: Retry loop without context cancellation check — pkg/connector/group.go:101-112

The retry loop for the flaky Jamf API uses time.Sleep(time.Second) without checking ctx.Done():

for count < 5 {
    group, err = g.client.GetGroupDetails(ctx, groupId)
    if err != nil {
        return nil, nil, err
    }
    if len(group.Members) > 0 {
        break
    }
    count++
    time.Sleep(time.Second)
}

If the context is cancelled, this will block for up to 5 seconds instead of returning promptly. Not introduced by this PR, so low priority.

Observations (Non-blocking)

  • main.go cleanup is excellent — the old 60-line boilerplate is now 10 clean lines using config.RunConnector. Well done.
  • SDK migration is consistent — all 6 builders (user, userAccount, userGroup, group, site, role) correctly use rs.SyncOpAttrs / *rs.SyncOpResults and 3-value returns.
  • Config generationconf.gen.go with reflection-based getters is standard for baton connectors. The panic("wrong type") in getters is acceptable since type mismatches are programming errors.
  • CI improvementssetup-go@v5, go-version-file instead of hardcoded version, golangci-lint-action@v8, and push-to-main trigger are all good upgrades.
  • lambda: false removed from release workflow — consistent with the new BATON_LAMBDA_SUPPORT build tag approach in the Makefile.
  • Securitygolang.org/x/crypto v0.44.0 and golang.org/x/oauth2 v0.32.0 are both patched for the 2025 CVEs (CVE-2025-22869 fixed in v0.35.0, CVE-2025-22868 fixed in v0.27.0). The CodeRabbit flags from earlier pushes no longer apply.

Verdict

The SDK migration is correctly applied. The only actionable issue is the unused parentResourceID in siteResource (pkg/connector/site.go:25) which is a bug — site resources will be missing parent relationships. Everything else looks good.


@laurenleach laurenleach marked this pull request as ready for review March 20, 2026 22:22
@laurenleach laurenleach merged commit 1f0f5e4 into main Mar 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants