Skip to content

parallelworks/pw-activate-scim-sync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pw-activate-scim-sync

Stateless reconciler that pushes ACTIVATE users, groups, and SSH public keys into CoreWeave's SCIM endpoint. Once records land in CoreWeave IAM, CoreWeave's AUP (Automated User Provisioning) and SUP (SUNK User Provisioning) propagate identities into CKS and SUNK clusters.

This is the companion to pw-activate-ldap. The two repos are alternatives, not layered:

  • pw-activate-ldap: PW operates an LDAP directory; SUNK binds to it. PW-managed staging point.
  • pw-activate-scim-sync: CoreWeave IAM is the staging point; PW just pushes records into it. AUP/SUP handle the rest.

Pick whichever side of the line your customer prefers.

Architecture

+------------------+         +-----------------+        +----------------+
| ACTIVATE control |  REST   |    syncer       |  HTTPS |  CoreWeave     |
|     plane        |<--------|   (CronJob)     |------->|  SCIM endpoint |
+------------------+         +-----------------+        +----------------+
        ^                                                       |
        | pw ssh-public-keys (subprocess)                       v
        |                                                +----------------+
        +------------------------------------------------|  CoreWeave IAM |
                                                         +----------------+
                                                                 |
                                                          AUP + SUP
                                                                 |
                                                                 v
                                                       +------------------+
                                                       | CKS + SUNK login |
                                                       +------------------+

The syncer is stateless; each run is a full reconciliation. State lives only in CoreWeave IAM. Records the syncer manages carry an externalId of pw-activate:user:<key> or pw-activate:group:<id>, and the syncer's SCIM list calls filter on that prefix, so anything in CW IAM without the prefix is invisible and untouched.

Notes that shape the design:

  • No uid/gid allocator. SUP assigns POSIX numbers downstream; this syncer only pushes the identity records.
  • CoreWeave's SCIM endpoint is one-way. CW does not push back; we treat ACTIVATE as authoritative.
  • Nested groups are not supported by the CW SCIM endpoint, so groups carry flat user references only.
  • Users removed from ACTIVATE are deactivated (active: false), not hard-deleted. SUP treats deactivation as the deprovisioning signal.

CoreWeave's docs for the downstream half:

Repo layout

pw-activate-scim-sync/
  src/pw_scim_sync/
    activate/         ACTIVATE REST client + pw ssh-public-keys shim
    scim_dest/        SCIM 2.0 client, resource models, mapper
    sync/             diff + apply (the reconciler core)
  tests/              diff and config unit tests
  k8s/                CronJob, ConfigMap, Secret
  Dockerfile          builds the syncer image
  pyproject.toml
  env.example         local-dev env

Deploy

# 1. Get the SCIM URL path segment and bearer token from CW Console.
#    Console -> Identity -> SCIM. Drop them into secret.example.yaml.

# 2. Edit configmap.example.yaml and secret.example.yaml.
kubectl apply -f k8s/configmap.example.yaml
kubectl apply -f k8s/secret.example.yaml
kubectl apply -f k8s/cronjob.yaml

# 3. Trigger a manual run to validate end-to-end.
kubectl -n pw-scim create job initial-sync \
  --from=cronjob/pw-activate-scim-sync
kubectl -n pw-scim logs job/initial-sync -f

Local development

uv sync
cp env.example .env
# fill in ACTIVATE_API_KEY, ACTIVATE_ORG_*, CW_SCIM_ORG_USERID, CW_SCIM_BEARER_TOKEN

uv run pw-activate-scim-sync --dry-run
uv run pw-activate-scim-sync

uv run pytest

The diff layer (src/pw_scim_sync/sync/diff.py) has no I/O and is the primary unit-test target.

Selecting which groups to sync

By default the syncer projects every group in the ACTIVATE org. To restrict to a subset, set ACTIVATE_SYNC_GROUPS to a comma-separated list of group names. Users who are not members of any selected group are not synced and any SCIM records the syncer previously created for them will be deactivated on the next run, so think of this as a hard scope, not a hint.

ACTIVATE_SYNC_GROUPS=hpc-users,research-team,gpu-pilot

Filter values are matched by ACTIVATE group name (not slug, not ID). Names in the filter that do not exist in ACTIVATE are logged as warnings but do not fail the run.

SCIM operations used

The syncer is not a full SCIM 2.0 server. It only consumes what AUP needs:

  • GET /Users?filter=externalId sw "pw-activate:": list managed users
  • POST /Users: create user
  • PATCH /Users/<id>: replace SSH keys (urn:coreweave:params:scim:schemas:extension:coreweave:2.0:CoreWeaveUser:sunkSshKeys), toggle active
  • GET /Groups?filter=externalId sw "pw-activate:": list managed groups
  • POST /Groups: create group
  • PATCH /Groups/<id>: replace members

The User resource carries the CoreWeave extension urn:coreweave:params:scim:schemas:extension:coreweave:2.0:CoreWeaveUser with a sunkSshKeys array; SUP reads that field when projecting POSIX login state.

Bearer token rotation

CW_SCIM_BEARER_TOKEN is issued from CW Console and is the only credential this syncer holds. To rotate, issue a new token in Console, update the pw-activate-scim-sync Secret, then revoke the old token. The next CronJob run picks up the new value; in-flight Jobs continue with the old token until they finish.

About

Sync ACTIVATE users, groups, and SSH keys to CoreWeave IAM via SCIM, triggering AUP/SUP to propagate into CKS and SUNK. Companion to pw-activate-ldap.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors