Skip to content

Bootstrap and Service Accounts

The bootstrap module resolves a critical “chicken-and-egg” authentication problem present in DAP 2.0.0.1, where the orchestrator’s REST API requires on-prem-issued tokens, but the token service lacks an operator-usable admin client by default . To bypass the need for the portal’s OIDC code-flow callback - which suffers from intermittent upstream bugs - the system provisions an admin service account by cloning the secret hash of an existing internal client . This process ensures idempotent state management by persisting deterministic UUIDs to a local state file before any database mutations, allowing partial-failure retries to reuse identifiers and prevent orphaned resources .

The core provisioning logic resides in provision_admin_client, which executes a three-step SQL insertion sequence against the iam_mgmt_svc database . First, it retrieves the secret and salt from a template client row specified by the operator . It then inserts a new clients row using these cloned credentials, a new roles row for the specified realm (defaulting to “Administrator”), and a linking client_roles row . All SQL statements utilize WHERE NOT EXISTS guards to ensure idempotency, meaning repeated executions will not create duplicate rows .

After database mutations, the system mints an on-prem token using the cloned secret and verifies that the token claims include the requested role . If the token lacks the expected role, a DapError is raised . The resulting credentials are returned as a BootstrapResult dataclass .

diagram

To prevent resource orphans during partial failures, the bootstrap process persists planned UUIDs to disk before executing any SQL mutations . The resolve_plan function in src/dap/bootstrap/state.py determines the UUIDs to use, following a specific precedence: explicit command-line overrides take priority, followed by any previously saved plan, and finally deterministic derivation .

UUIDs are derived deterministically using uuid.uuid5 based on the cluster_org_id and client_name . This ensures that two operators running the bootstrap with the same inputs converge on the same identifiers . The plan is saved atomically to a JSON file in ~/.config/dap-cli/bootstrap-state/ with mode 0600 . If a run fails, a retry will load the existing plan and reuse the same IDs, ensuring the database WHERE NOT EXISTS guards prevent duplicate entries while completing the missing rows .

The bootstrap relies on cloning the hash of an existing internal service account rather than generating a new random secret . The iam-mgmt-svc validates client credentials by comparing the hash of the provided plaintext against the stored (secret, salt) pair . By inserting a new client row with the same secret and salt as a known template, the new client can authenticate using the template’s known plaintext password .

Security is maintained through strict input handling. The template client’s plaintext password and the PostgreSQL superuser password are never accepted via environment variables or command-line arguments . Instead, they are read via the dap.secret_input.read_secret helper, which supports interactive hidden prompts, stdin piping, or file-based input . SQL injection is mitigated by wrapping all interpolated values in _lit(), which escapes single quotes, and by shell-quoting the entire query string passed to psql .

Upon successful provisioning, the persist function saves the BootstrapResult to a JSON file at ~/.config/dap-cli/api-client.json with restricted permissions (0600) . This file contains the cluster name, client ID, client secret, role ID, and role name .

The load_persisted function allows the system to retrieve these credentials for subsequent operations . It validates that the persisted file exists and that the cluster name in the file matches the current cluster configuration . If the file is missing or mismatched, it raises a DapError instructing the user to run the bootstrap command .