Skip to content

parallelworks/pw-activate-ldap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pw-activate-ldap

LDAP service backed by ACTIVATE. The repo is a single deployable that bundles two components: an OpenLDAP server PW operates and a syncer that keeps the directory in sync with ACTIVATE. Downstream consumers (SUNK nsscache, sssd, getent) bind to the LDAP service and never need to know that ACTIVATE exists.

This is the LDAP analog of pw-slurm-group-sync. The two are complementary; pw-slurm-group-sync writes Slurm accounts via sacctmgr, this writes POSIX identity and SSH public keys via LDAP.

Architecture

+------------------+        +-----------------+        +--------------+
| ACTIVATE control |  REST  |    syncer       |  ldap3 |  OpenLDAP    |
|     plane        |<-------|   (CronJob)     |------->|  StatefulSet |
+------------------+        +-----------------+        +--------------+
        ^                                                      |
        | pw ssh-public-keys (subprocess)                      | LDAPS
        +------------------------------------------------------|
                                                                v
                                                        +--------------+
                                                        | SUNK login   |
                                                        | pod (nsscache|
                                                        |  / sssd)     |
                                                        +--------------+

The syncer is stateless; each run is a full reconciliation. State lives only in LDAP, under ou=pw-managed,<base>. Anything outside that subtree is invisible to the syncer, so the directory can host other records (service accounts, manually-managed entries) without risk.

Repo layout

pw-activate-ldap/
  src/pw_ldap_sync/         syncer source
  tests/                    diff unit tests
  k8s/
    ldap-server/            OpenLDAP StatefulSet, Service, schema, bootstrap
    syncer/                 CronJob, ConfigMap, Secret
  Dockerfile                builds the syncer image
  pyproject.toml
  env.example               local-dev env

Deploy

The bring-up has three phases. The full sequence:

# 1. LDAP server, see k8s/ldap-server/README.md
kubectl apply -f k8s/ldap-server/00-namespace.yaml
# generate real openldap-admin and openldap-tls secrets, then:
kubectl apply -f k8s/ldap-server/20-schema-configmap.yaml
kubectl apply -f k8s/ldap-server/30-service.yaml
kubectl apply -f k8s/ldap-server/40-statefulset.yaml
kubectl -n pw-ldap rollout status statefulset/openldap

# 2. Syncer, see k8s/syncer/README.md
# replace placeholders in k8s/syncer/configmap.example.yaml and secret.example.yaml first
kubectl apply -f k8s/syncer/configmap.example.yaml
kubectl apply -f k8s/syncer/secret.example.yaml
kubectl apply -f k8s/syncer/cronjob.yaml

# 3. Verify end-to-end
kubectl -n pw-ldap create job initial-sync \
  --from=cronjob/pw-activate-ldap-sync
kubectl -n pw-ldap logs job/initial-sync -f

kubectl -n pw-ldap run check --rm -it --image=bitnami/openldap:2.6 -- \
  ldapsearch -x -H ldaps://ldap.pw-ldap.svc:636 \
  -D "cn=admin,dc=pw-managed,dc=local" -w "$ADMIN_PASSWORD" \
  -b "ou=people,ou=pw-managed,dc=pw-managed,dc=local" "(objectClass=posixAccount)" \
  uid uidNumber sshPublicKey

The LDAP service that downstream consumers bind to is ldaps://ldap.pw-ldap.svc:636 for in-cluster access. To expose it across clusters or for external consumers, front the Service with a LoadBalancer, an Ingress with TLS passthrough, or expose through a ServiceMesh gateway.

Local development of the syncer

uv sync
cp env.example .env
# fill in ACTIVATE_API_KEY, ACTIVATE_ORG_*, LDAP_*, point LDAP_URI at a dev directory

uv run pw-activate-ldap-sync --dry-run
uv run pw-activate-ldap-sync

uv run pytest

The diff layer (src/pw_ldap_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 LDAP records the syncer previously created for them will be deleted 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.

Bind-account hardening (post-v1)

The default deployment has the syncer bind as cn=admin,dc=pw-managed,dc=local, which is convenient for getting started but grants more than the syncer needs. For production, create a dedicated service account and scope its write access to the management subtree:

dn: cn=svc-syncer,ou=services,dc=pw-managed,dc=local
objectClass: organizationalRole
objectClass: simpleSecurityObject
cn: svc-syncer
userPassword: {SSHA}<hash>
description: pw-activate-ldap-sync bind account

# olcAccess directives granting the account write to ou=pw-managed only

Then update LDAP_BIND_DN in the syncer ConfigMap and rotate the syncer Secret to the new password.

Consumer configuration (SUNK nsscache)

The downstream config that closes the loop. SUNK's directory-services.ldap chart values look like (paraphrased; check the SUNK chart values for the exact schema):

directoryServices:
  ldap:
    uri: "ldaps://ldap.pw-ldap.svc:636"
    base: "ou=pw-managed,dc=pw-managed,dc=local"
    binddn: "cn=ro-bind,ou=services,dc=pw-managed,dc=local"
    bindpwFile: "/etc/openldap/secret"
    tls:
      cacertFile: "/etc/openldap/ca.crt"
    nss:
      passwd:
        base: "ou=people,ou=pw-managed,dc=pw-managed,dc=local"
      group:
        base: "ou=groups,ou=pw-managed,dc=pw-managed,dc=local"
      sshPublicKey:
        attribute: "sshPublicKey"

A read-only bind account scoped to read ou=pw-managed is the recommended pattern; it never needs write access and is what nsscache binds with.

About

LDAP service backed by Parallel Works ACTIVATE. OpenLDAP server plus a syncer that projects users, groups, and SSH public keys into the directory.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors