Synit ADProxy
Beispiele
Praxisnahe Synit ADProxy Beispiele für Plan-only, Apply, Benutzeranlage, Gruppen, Account-Einstellungen, Queries, JSON-RPC und Templates.
Beispiele
Diese Beispiele zeigen typische Request-Muster für Enterprise Active Directory. .example.test Domains und Platzhalter dienen nur als Orientierung. Produktive DNs, Tokens, Benutzer, Gruppen und Passwörter gehören nicht in öffentliche Repositories.
Plan-only und Apply trennen
Plan-only ist der empfohlene Start. Der Plan liest den aktuellen Active-Directory-Zustand, prüft Regeln, ordnet Abhängigkeiten und liefert ein Ergebnis, ohne zu schreiben.
curl -sS -X POST https://adproxy.example.test/api/v1/mutations/plan \
-H "Authorization: Bearer <read-or-write-token>" \
-H "Content-Type: application/json" \
-d '{
"mutation_id": "group-access-jane",
"actor": "alice@example.test",
"source": "service-desk",
"response_detail": "standard",
"operations": [
{
"id": "add_jane_to_engineering",
"operation_type": "add_group_member",
"target": {
"dn": "CN=Engineering Users,OU=Groups,DC=example,DC=test"
},
"object_class": "group",
"member_dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
}
]
}'
Wenn der Plan akzeptiert wurde, wird nur die plan_id angewendet:
curl -sS -X POST https://adproxy.example.test/api/v1/mutations/apply \
-H "Authorization: Bearer <write-token>" \
-H "Content-Type: application/json" \
-d '{
"plan_id": "<plan-id-aus-plan-response>",
"actor": "alice@example.test"
}'
Für sensible Operationen kann zusätzlich force oder eine Approval-Policy erforderlich sein.
Idempotente kombinierte Ausführung
Der kombinierte Endpoint plant und wendet in einem Request an. Für technische Retries sollte ein stabiler Idempotency-Key gesetzt werden.
curl -sS -X POST https://adproxy.example.test/api/v1/mutations \
-H "Authorization: Bearer <write-token>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: onboard-jane-2026-07-01" \
-d @request.json
Ein erneuter Request mit gleichem Key und gleichem Body liefert dasselbe Ergebnis zurück. Ein gleicher Key mit anderem Body wird abgelehnt.
Operationen
Benutzer anlegen
{
"mutation_id": "create-jane",
"actor": "alice@example.test",
"source": "iam-workflow",
"operations": [
{
"id": "create_jane",
"operation_type": "create_user",
"target": {
"dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
},
"object_class": "user",
"attributes": {
"cn": "Jane Doe",
"givenName": "Jane",
"sn": "Doe",
"displayName": "Jane Doe",
"sAMAccountName": "jdoe",
"userPrincipalName": "jdoe@example.test",
"mail": "jane.doe@example.test",
"department": "Engineering"
}
}
]
}
Benutzer anlegen und Gruppe setzen
{
"mutation_id": "onboard-jane",
"actor": "alice@example.test",
"source": "iam-workflow",
"operations": [
{
"id": "create_jane",
"operation_type": "create_user",
"target": {
"dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
},
"object_class": "user",
"attributes": {
"cn": "Jane Doe",
"givenName": "Jane",
"sn": "Doe",
"displayName": "Jane Doe",
"sAMAccountName": "jdoe",
"userPrincipalName": "jdoe@example.test",
"mail": "jane.doe@example.test"
}
},
{
"id": "add_jane_to_engineering",
"operation_type": "add_group_member",
"target": {
"dn": "CN=Engineering Users,OU=Groups,DC=example,DC=test"
},
"object_class": "group",
"member_dn": "CN=Jane Doe,OU=Users,DC=example,DC=test",
"depends_on": ["create_jane"]
}
]
}
Passwort setzen
{
"force": true,
"show_secret_outputs": true,
"operations": [
{
"id": "set_initial_password",
"operation_type": "set_password",
"target": {
"dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
},
"object_class": "user",
"generated_password": {
"output_name": "jane.initial_password",
"length": 24
}
}
]
}
Generierte Passwörter werden nur in der Apply-Antwort ausgegeben, wenn show_secret_outputs gesetzt ist. Sie werden nicht in Audit, Snapshot oder Mutation History gespeichert.
Attribute ändern
{
"operations": [
{
"id": "update_title",
"operation_type": "modify_attributes",
"target": {
"sAMAccountName": "jdoe"
},
"object_class": "user",
"attributes": {
"title": "Senior Engineer",
"telephoneNumber": "__DELETE__"
}
}
]
}
Account deaktivieren und verschieben
{
"mutation_id": "offboard-jane",
"actor": "alice@example.test",
"source": "service-desk",
"force": true,
"operations": [
{
"id": "disable_user",
"operation_type": "disable_account",
"target": {
"dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
},
"object_class": "user"
},
{
"id": "remove_from_engineering",
"operation_type": "remove_group_member",
"target": {
"dn": "CN=Engineering Users,OU=Groups,DC=example,DC=test"
},
"object_class": "group",
"member_dn": "CN=Jane Doe,OU=Users,DC=example,DC=test",
"depends_on": ["disable_user"]
},
{
"id": "move_to_disabled_ou",
"operation_type": "move_object",
"target": {
"dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
},
"object_class": "user",
"new_parent": "OU=Disabled Users,DC=example,DC=test",
"depends_on": ["disable_user"]
}
]
}
Manager setzen
{
"operations": [
{
"id": "set_manager",
"operation_type": "set_manager",
"target": {
"sAMAccountName": "jdoe"
},
"object_class": "user",
"manager_dn": "CN=Erika Manager,OU=Users,DC=example,DC=test"
}
]
}
Account-Einstellungen ändern
{
"force": true,
"operations": [
{
"id": "update_settings",
"operation_type": "update_account_settings",
"target": {
"sAMAccountName": "jdoe"
},
"object_class": "user",
"account_settings": {
"enabled": true,
"expires_at": "2026-12-31T23:59:59Z",
"password_never_expires": false,
"must_change_password_at_next_logon": true,
"cannot_change_password": false,
"smartcard_required": false,
"delegation_allowed": false,
"logon_to": ["WS1", "WS2"]
}
}
]
}
Objekt suchen und Ergebnis weiterverwenden
lookup_object kann ein Objekt suchen. Spätere Operationen können das Ergebnis referenzieren.
{
"operations": [
{
"id": "find_user",
"operation_type": "lookup_object",
"target": {
"sAMAccountName": "jdoe"
},
"object_class": "user"
},
{
"id": "move_user",
"operation_type": "move_object",
"object_class": "user",
"target": {
"dn": "$.operations['find_user'].Result.DistinguishedName"
},
"new_parent": "OU=Engineering,DC=example,DC=test",
"depends_on": ["find_user"]
}
]
}
Desired-State Beispiele
Desired-State Requests beschreiben den Zielzustand. ADProxy liest den aktuellen Zustand und plant die nötigen Schritte.
Benutzer-Zielzustand
{
"force": true,
"show_secret_outputs": true,
"desired_users": [
{
"name": "jane",
"dn": "CN=Jane Doe,OU=Users,DC=example,DC=test",
"attributes": {
"mail": {
"mode": "exact",
"values": ["jane.doe@example.test"]
},
"department": {
"mode": "exact",
"values": ["Engineering"]
}
},
"generated_password": {
"output_name": "jane.initial_password",
"length": 24
},
"enabled": true,
"groups": ["CN=Engineering Users,OU=Groups,DC=example,DC=test"],
"move_to_ou_dn": "OU=Engineering,DC=example,DC=test"
}
]
}
Gruppen-Zielzustand
{
"desired_groups": [
{
"name": "engineering_users",
"dn": "CN=Engineering Users,OU=Groups,DC=example,DC=test",
"group_type": "security",
"group_scope": "global",
"members": [
"CN=Jane Doe,OU=Users,DC=example,DC=test",
"CN=Bob Smith,OU=Users,DC=example,DC=test"
],
"manager_dn": "CN=Erika Manager,OU=Users,DC=example,DC=test"
}
]
}
Objekt entfernen
{
"desired_objects": [
{
"name": "old_group",
"object_class": "group",
"dn": "CN=Old Group,OU=Groups,DC=example,DC=test",
"absent": true
}
]
}
Read-only Queries
Diese Abfragen schreiben nie in Active Directory.
curl -sS -X POST https://adproxy.example.test/api/v1/query \
-H "Authorization: Bearer <read-token>" \
-H "Content-Type: application/json" \
-d '{"operation":"search_user_by_sam","parameters":{"sam_account_name":"jdoe"}}'
curl -sS -X POST https://adproxy.example.test/api/v1/query \
-H "Authorization: Bearer <read-token>" \
-H "Content-Type: application/json" \
-d '{"operation":"search_user_by_mail","parameters":{"mail":"jane.doe@example.test"}}'
curl -sS -X POST https://adproxy.example.test/api/v1/query \
-H "Authorization: Bearer <read-token>" \
-H "Content-Type: application/json" \
-d '{"operation":"list_group_members","parameters":{"group_dn":"CN=Engineering Users,OU=Groups,DC=example,DC=test","recursive":true}}'
curl -sS -X POST https://adproxy.example.test/api/v1/query \
-H "Authorization: Bearer <read-token>" \
-H "Content-Type: application/json" \
-d '{"operation":"get_object","parameters":{"dn":"CN=Jane Doe,OU=Users,DC=example,DC=test","force_refresh":true}}'
JSON-RPC
JSON-RPC nutzt denselben Plan/Apply-Kern.
curl -sS -X POST https://adproxy.example.test/api/v1/rpc \
-H "Authorization: Bearer <read-or-write-token>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "mutation.plan",
"params": {
"actor": "alice@example.test",
"operations": [
{
"id": "add_member",
"operation_type": "add_group_member",
"target": {
"dn": "CN=Engineering Users,OU=Groups,DC=example,DC=test"
},
"object_class": "group",
"member_dn": "CN=Jane Doe,OU=Users,DC=example,DC=test"
}
]
}
}'
Apply per JSON-RPC:
{
"jsonrpc": "2.0",
"id": 2,
"method": "mutation.apply",
"params": {
"plan_id": "<plan-id>",
"actor": "alice@example.test"
}
}
Schema-Endpunkte
Schema-Endpunkte helfen Integrationen, gültige Requests zu bauen.
curl -sS -u "<client-id>:<secret>" https://adproxy.example.test/api/v1/schema
curl -sS -u "<client-id>:<secret>" https://adproxy.example.test/api/v1/schema/classes/user
curl -sS -u "<client-id>:<secret>" https://adproxy.example.test/api/v1/schema/attributes/sAMAccountName
Template: Onboarding
user_onboarding.template.json:
{
"name": "user_onboarding",
"payload": {
"mutation_id": "{{ $mutation_id }}",
"actor": "{{ $actor }}",
"operations": [
{
"id": "create_user",
"operation_type": "create_user",
"object_class": "user",
"target": {
"dn": "CN={{ $display_name }},{{ $ou_dn }}"
},
"attributes": {
"cn": "{{ $display_name }}",
"givenName": "{{ $given_name }}",
"sn": "{{ $surname }}",
"sAMAccountName": "{{ $user_name }}",
"mail": "{{ $user_name }}@example.test",
"company": "{{ $company }}",
"department": "{{ $department }}"
}
},
{
"id": "add_to_group",
"operation_type": "add_group_member",
"target": {
"dn": "{{ $primary_group_dn }}"
},
"object_class": "group",
"member_dn": "CN={{ $display_name }},{{ $ou_dn }}",
"depends_on": ["create_user"]
}
]
}
}
Plan aus Template:
curl -sS -X POST https://adproxy.example.test/api/v1/templates/user_onboarding/plan \
-H "Authorization: Bearer <read-or-write-token>" \
-H "Content-Type: application/json" \
-d '{
"mutation_id": "onboard-jane",
"actor": "alice@example.test",
"display_name": "Jane Doe",
"given_name": "Jane",
"surname": "Doe",
"user_name": "jdoe",
"company": "Example GmbH",
"department": "Engineering",
"ou_dn": "OU=Users,DC=example,DC=test",
"primary_group_dn": "CN=Engineering Users,OU=Groups,DC=example,DC=test"
}'
Template: Offboarding
{
"name": "user_offboarding",
"payload": {
"mutation_id": "{{ $mutation_id }}",
"actor": "{{ $actor }}",
"force": true,
"operations": [
{
"id": "disable_user",
"operation_type": "disable_account",
"target": {
"dn": "{{ $user_dn }}"
},
"object_class": "user"
},
{
"id": "remove_from_group",
"operation_type": "remove_group_member",
"target": {
"dn": "{{ $group_dn }}"
},
"object_class": "group",
"member_dn": "{{ $user_dn }}",
"depends_on": ["disable_user"]
},
{
"id": "move_to_disabled_ou",
"operation_type": "move_object",
"target": {
"dn": "{{ $user_dn }}"
},
"object_class": "user",
"new_parent": "{{ $disabled_ou_dn }}",
"depends_on": ["disable_user"]
}
]
}
}
Regeln für produktive Beispiele
operations, desired_users, desired_groups und desired_objects nicht in einem Request mischen. Operationen mit set_password, enable_account, disable_account, unlock oder update_account_settings benötigen in der Regel force oder eine passende Approval-Policy. Generated Secrets nur für die direkte Weitergabe an freigegebene Zielsysteme anzeigen lassen. Vor dem ersten Apply immer einen Plan-only Durchlauf prüfen.