Guide 02

User guide

How to operate a running lab. If you do not have one yet, start at the quick start. To seed users and groups from YAML, see Scenario YAML.

Sign-in

Static bearer tokens are an explicit lab mode.

  • Browser — paste the token on /login. You get an HttpOnly session cookie. The CSRF secret stays in page memory, never in localStorage.
  • REST / HTTP MCPAuthorization: Bearer
  • stdio MCP--token-file or LABLDAP_MCP_TOKEN. Never --token.
  • Direct LDAP — simple bind as a directory user. The control-plane token is not an LDAP password.

Scenario YAML

Users and groups are declared in the LabScenario file. Bootstrap writes them into 389 DS. Passwords are file references. Groups cannot be empty. Soft reset restores that file.

spec:
  users:
    - id: alice
      uid: alice
      passwordFile: /run/secrets/user-alice
      enabled: true
  groups:
    - id: staff
      members:
        - user: alice

Full mapping and ACL example: Scenario YAML.

Browser UI

Open https://127.0.0.1:8443/. Trust the lab CA or accept the warning.

  • / dashboard — scenario, engine, baseline, transports, recent audit
  • /users create, edit, enable/disable, set password, delete (type the id)
  • /groups create with an initial member; add / remove / replace membership
  • /search explicit-submit LDAP search; userPassword cannot be requested
  • /auth-test bind diagnostic; password field clears after
  • /schema read-only Root DSE and schema
  • /audit in-memory ring, request-id copy
  • /export LDIF without passwords
  • /reset soft reset to the compiled baseline

Updates carry a revision. A 412 means refresh and retry. Groups cannot be empty. Soft reset needs the exact scenario name. Hard reset is make compose-reset only.

REST

Base URL https://127.0.0.1:8443/api/v1. Contract: api/openapi.yaml.

TOKEN=$(tr -d '\n' < secrets/token-admin)
curl -sk -H "Authorization: Bearer $TOKEN" \
  https://127.0.0.1:8443/api/v1/users

GET /health never talks to LDAP. GET /health/ready does. GET /metrics is Prometheus text on loopback.

Direct LDAP

Yes — you can authenticate against the lab as an LDAP server. The listener is 389 Directory Server, not the Go control plane. Point clients at 127.0.0.1:3389 (StartTLS) or 127.0.0.1:3636 (LDAPS). Do not point an LDAP client at :8443; that port is HTTPS.

Anonymous bind is off. Cleartext bind is off. Trust secrets/tls/instance-ca.crt (ephemeral) or secrets/tls/ca.crt (persistent). Wrong CA or SAN fails closed.

MCP

Two transports, one catalog, same scopes as REST.

  • HTTP: POST /mcp with a bearer. GET /mcp is 405.
  • Local: labldap mcp-stdio — protocol on stdout, logs on stderr.

On by default: ldap_search_entries, ldap_get_capabilities, ldap_get_baseline, ldap_get_entry.

Off until register*: create/update/delete user and group, membership, passwords, reset, export.

Resources include labldap://capabilities, labldap://baseline, labldap://schema, and labldap://entry{?dn}.

What not to do

  • Do not put Directory Manager in the control container.
  • Do not mount the Docker socket.
  • Do not treat ephemeral tmpfs as a wipe.
  • Do not expect Active Directory semantics.
  • Do not log tokens, passwords, or session ids.

Full version: docs/guides/user-guide.md. MCP table: docs/mcp/catalog.md.