Skip to content

✨ Add Rippling provider (company / workforce / org structure)#7695

Open
tas50 wants to merge 2 commits into
mainfrom
worktree-rippling-provider
Open

✨ Add Rippling provider (company / workforce / org structure)#7695
tas50 wants to merge 2 commits into
mainfrom
worktree-rippling-provider

Conversation

@tas50

@tas50 tas50 commented May 14, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds providers/rippling, a new SaaS provider that exposes the company profile, workforce, and org structure of a Rippling-managed company. Auth is OAuth 2.0 — the provider takes a client ID, client secret, and refresh token via --client-id / --client-secret / --refresh-token (or RIPPLING_CLIENT_ID / RIPPLING_CLIENT_SECRET / RIPPLING_REFRESH_TOKEN).
  • Resources: rippling, rippling.company, rippling.employee, rippling.department, rippling.team, rippling.workLocation, rippling.group. Compensation, benefits, and payroll-mechanics fields are intentionally not modeled — the provider is scoped to identity, org structure, and access auditing.
  • Lightweight in-repo HTTP client over the Rippling Platform REST API (no Go SDK exists). Pagination handled via limit/offset query parameters; covered by a unit test on the pagination math.

Authentication

  • Rippling supports an OAuth 2.0 authorization-code grant. Register an app in the Rippling developer portal, complete the authorization once to obtain a refresh token, then hand mql the client ID, client secret, and refresh token.
  • mql exchanges the refresh token for short-lived access tokens via golang.org/x/oauth2; the access token is refreshed automatically as it expires. No static API token is involved.

What you can audit

  • Every active employee has a department, team, and primary work location
  • Terminated employees have terminated=true and no remaining manager reports
  • The company's primary contact email uses a recognizable corporate domain
  • Every group named like a privileged role (Admin, Finance, …) has a bounded membership
  • Employee roleStatus values stay within the documented set (ACTIVE, TERMINATED, LEAVE_OF_ABSENCE)

Files of interest

  • providers/rippling/resources/rippling.lr — schema
  • providers/rippling/connection/client.go — REST client + paginator
  • providers/rippling/connection/client_test.go — pagination math unit test
  • providers/rippling/connection/connection.go — OAuth credential handling and asset identifier
  • providers/rippling/provider/provider.go — flag handling and asset detection

Notes for review

  • Modeled on the Gusto provider (✨ Add Gusto provider (company / workforce / admin access) #7693). Same overall shape (in-repo REST client, lazily-resolved typed cross-refs, single-page-walk listing), but Gusto authenticates with a static API token while Rippling uses OAuth 2.0.
  • Rippling OAuth tokens are scoped to a single company, so rippling.companies() is always a one-element list (kept plural to match the rest of the schema and avoid a name clash with rippling.company).
  • Field names mirror what the Rippling Platform API documents publicly. I haven't been able to verify against a live tenant in this session — please run the test plan below before merging.

Test plan

  • make providers/build/rippling succeeds
  • make providers/install/rippling && mql shell rippling --client-id $RIPPLING_CLIENT_ID --client-secret $RIPPLING_CLIENT_SECRET --refresh-token $RIPPLING_REFRESH_TOKEN
    • rippling.companies { name legalName }
    • rippling.employees.where(terminated == false) { workEmail department { name } }
    • rippling.departments { name parent { name } }
    • rippling.workLocations { nickname city state }
    • rippling.groups { name members.length }
  • Invalid or expired OAuth credentials return a clear error on connect
  • An expired access token is transparently refreshed mid-session
  • Optional --api-base override works for a custom Rippling base URL

🤖 Generated with Claude Code

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cross-reference fields (manager, department, team, parent, members) silently return null when a resource is resolved by ID rather than from a list.

Comment thread providers/rippling/resources/employee.go
Comment thread providers/rippling/resources/department.go
Comment thread providers/rippling/resources/team.go
Comment thread providers/rippling/resources/group.go
Comment thread providers/rippling/connection/client.go
Comment thread providers/rippling/connection/client.go
Comment thread providers/rippling/resources/rippling.lr
@github-actions

github-actions Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Test Results

6 030 tests  ±0   6 026 ✅ ±0   3m 13s ⏱️ -9s
  292 suites ±0       2 💤 ±0 
    4 files   ±0       2 ❌ ±0 

For more details on these failures, see this check.

Results for commit d856125. ± Comparison against base commit 629c9c2.

♻️ This comment has been updated with latest results.

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Resolving resources by ID (e.g. rippling.employee(id: "xxx").manager) silently returns null because init functions never populate internal struct cache fields

Comment thread providers/rippling/resources/employee.go Outdated
Comment thread providers/rippling/resources/department.go Outdated
Comment thread providers/rippling/resources/team.go Outdated
Comment thread providers/rippling/resources/group.go Outdated
Comment thread providers/rippling/connection/connection.go
Comment thread providers/rippling/config/config.go
@mondoo-code-review mondoo-code-review Bot dismissed their stale review May 15, 2026 20:01

Superseded by new review

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Init functions now correctly populate internal structs for cross-reference resolution.

@tas50 tas50 force-pushed the worktree-rippling-provider branch from d856125 to c535b8e Compare May 21, 2026 05:13

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New Rippling provider exposes company, workforce, and org structure data via OAuth-authenticated API; sensitive field (TIN) is exposed without warning.

Comment thread providers/rippling/resources/rippling.lr
Comment thread providers/rippling/resources/rippling.lr
Comment thread providers/rippling/connection/client.go
Comment thread providers/rippling/connection/client.go
Comment thread providers/rippling/resources/department.go
@tas50 tas50 closed this May 21, 2026
@tas50 tas50 reopened this May 21, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators May 21, 2026
@tas50 tas50 force-pushed the worktree-rippling-provider branch 2 times, most recently from 846108c to b2f07f8 Compare May 22, 2026 06:45
@tas50

tas50 commented May 22, 2026

Copy link
Copy Markdown
Member Author

/review

@tas50 tas50 force-pushed the worktree-rippling-provider branch 2 times, most recently from 3a29d73 to 6c5d436 Compare May 26, 2026 16:12
tas50 and others added 2 commits June 3, 2026 09:58
Adds providers/rippling, a new SaaS provider that exposes the company
profile, workforce, and org structure of a Rippling-managed company.
Auth is a Rippling Platform API token via --token or RIPPLING_API_TOKEN.

Resources: rippling, rippling.company, rippling.employee, rippling.department,
rippling.team, rippling.workLocation, rippling.group. Compensation, benefits,
and payroll-mechanics fields are intentionally not modeled — the provider is
scoped to identity, org structure, and access auditing.

Lightweight in-repo HTTP client over the Rippling Platform REST API (no Go
SDK exists). Pagination handled via limit/offset query parameters; the
math is covered by a unit test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tas50 tas50 force-pushed the worktree-rippling-provider branch from 6c5d436 to e0e1ebd Compare June 3, 2026 16:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant