FreeIPA-API writes (user/group mutations) #3

Merged
supportgsc merged 1 commits from feat/freeipa-api-writes into main 2026-06-01 12:05:59 +00:00
Owner

Why

Raw LDAP adds/modifies bypassed FreeIPA's framework: group/user creates failed with Object Class Violation (no DNA-assigned gidNumber/uidNumber/ipaUniqueID, missing object classes) and deletes/mods couldn't be done as plain LDAP writes by the service bind account.

What

Route all mutations through the FreeIPA JSON-RPC API; reads stay on direct LDAP.

  • internal/client/freeipa.go (new): JSON-RPC client — form login_passwordipa_session cookie, re-auth on 401, multi-server failover, TLS via the configured CA. Derives the API host + login uid from the LDAP config.
  • internal/service/ldap.go: group_add/_mod/_del/_add_member/_remove_member; user_add/_mod/_disable/_enable/passwd. Services map → addattr(objectclass)/setattr. Writes error cleanly if the IPA client is unconfigured.
  • cmd/server/main.go: build + inject the FreeIPA client.

Ops prerequisites (done)

The bind account svc-ops-api was given a non-expiring service password policy (svc-accounts, maxlife=0) and rotated; bind creds now stored in Infisical so ops-api binds authenticated (reads) and authenticates the IPA API (writes). It holds the User Administrator role (incl. Group Administrators privilege).

Verified live (binary 1.2.0)

group create (IPA-assigned gidNumber), get, add/remove member, delete → all 200/201; reads unchanged. gscAdmin-continuum's group/user write actions (already on ops-api) now function.

🤖 Generated with Claude Code

## Why Raw LDAP adds/modifies bypassed FreeIPA's framework: group/user **creates** failed with `Object Class Violation` (no DNA-assigned `gidNumber`/`uidNumber`/`ipaUniqueID`, missing object classes) and deletes/mods couldn't be done as plain LDAP writes by the service bind account. ## What Route all **mutations** through the FreeIPA JSON-RPC API; **reads stay on direct LDAP**. - **`internal/client/freeipa.go`** (new): JSON-RPC client — form `login_password` → `ipa_session` cookie, re-auth on 401, multi-server failover, TLS via the configured CA. Derives the API host + login uid from the LDAP config. - **`internal/service/ldap.go`**: `group_add/_mod/_del/_add_member/_remove_member`; `user_add/_mod/_disable/_enable/passwd`. Services map → `addattr`(objectclass)/`setattr`. Writes error cleanly if the IPA client is unconfigured. - **`cmd/server/main.go`**: build + inject the FreeIPA client. ## Ops prerequisites (done) The bind account `svc-ops-api` was given a non-expiring service password policy (`svc-accounts`, maxlife=0) and rotated; bind creds now stored in Infisical so ops-api binds authenticated (reads) and authenticates the IPA API (writes). It holds the `User Administrator` role (incl. Group Administrators privilege). ## Verified live (binary 1.2.0) group create (IPA-assigned `gidNumber`), get, add/remove member, delete → all 200/201; reads unchanged. gscAdmin-continuum's group/user write actions (already on ops-api) now function. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
supportgsc added 1 commit 2026-06-01 12:05:44 +00:00
Raw LDAP adds/modifies bypassed FreeIPA's framework, so group/user creates
failed with Object Class Violation (no gidNumber/uidNumber/ipaUniqueID) and
deletes/mods needed ACIs the bind account couldn't exercise as a plain LDAP
write. Route all MUTATIONS through the FreeIPA JSON-RPC API instead; reads
stay on direct LDAP.

- internal/client/freeipa.go: new JSON-RPC client (form login_password →
  ipa_session cookie, re-auth on 401, multi-server failover, TLS via the
  configured CA). Derives the API host + login uid from the LDAP config.
- internal/service/ldap.go: CreateGroup/UpdateGroup/DeleteGroup/AddGroupMembers/
  RemoveGroupMember → group_add/_mod/_del/_add_member/_remove_member;
  CreateUser/UpdateUser/DisableUser/ResetPassword → user_add/_mod/_disable
  (+_enable)/passwd. Services map → addattr(objectclass)/setattr. Writes error
  cleanly when the IPA client is unconfigured.
- cmd/server/main.go: build the FreeIPA client from the LDAP config and inject
  it into the LDAP service.

Verified live: group create (IPA-assigned gidNumber), get, add/remove member,
delete all succeed; reads unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
supportgsc merged commit 66bfb4ebfa into main 2026-06-01 12:05:59 +00:00
supportgsc deleted branch feat/freeipa-api-writes 2026-06-01 12:06:03 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GoSec_Cloud/gsc-ops-api#3