Skip to content

Build dygo Control operator CLI with setup and browser authentication #258

Description

@thsnkhn

Goal

Build dygo Control, a remote operator CLI for running and administering a deployed dygo system.

The executable is dygoctl. It is separate from the existing dygo framework and project CLI, but it lives in the same repository and release process.

The first-run experience starts with:

dygoctl setup

The setup wizard asks for the deployment URL, verifies the deployment, opens the correct Studio authentication page, completes CLI authorization, stores the context and credential safely, and confirms that the operator can use the deployment.

Product boundary

dygo and dygoctl serve different users:

dygo     framework development, local project files, metadata, database lifecycle, and runtime processes
dygoctl  remote business and system operations through an authenticated deployment API

Keep both binaries in this repository so the server, client, authentication contracts, API envelopes, and releases can evolve together.

dygoctl must not:

  • require a dygo project checkout;
  • discover a local project root;
  • connect directly to PostgreSQL;
  • read deployment secret files;
  • import Business App or framework implementation packages to perform remote work;
  • create a second permission or business-operation path.

Studio and dygoctl must use the same server APIs, permission engine, Activity behavior, and Audit Log behavior.

Related work

This issue defines the dygo Control product and integration shape. Related authentication and Studio work can ship as linked subtasks without being duplicated here.

Repository shape

Start with a second binary in the current Go module:

cmd/
  dygo/
    main.go
  dygoctl/
    main.go

internal/
  cli/             existing framework and project CLI
  operatorcli/     dygo Control command tree and terminal behavior
  apiclient/       authenticated deployment HTTP client

Keep the API client internal until external Go consumers need a stable public client contract.

Setup wizard

Interactive flow

dygoctl setup performs these steps:

  1. Explain that dygo Control connects to an existing deployment.
  2. Ask for the deployment URL.
  3. Normalize the URL and remove an unnecessary trailing slash.
  4. Require HTTPS for remote deployments. Permit HTTP only for an explicit localhost development context.
  5. Call a public health or discovery endpoint.
  6. Confirm that the endpoint is a dygo deployment.
  7. Read the server version and supported capabilities.
  8. Detect an incompatible client and server before authentication.
  9. Suggest a context name from the deployment host.
  10. Ask the operator to confirm or change the context name.
  11. Start a short-lived CLI device-authorization request.
  12. Open the deployment's Studio authorization URL in the default browser.
  13. Print the URL and one-time code so setup still works when the browser cannot open.
  14. Let Studio redirect an unauthenticated operator to /login and return them to the authorization page after sign-in.
  15. Show the requested CLI access and target deployment in Studio.
  16. Require the operator to approve or deny the request.
  17. Poll the token endpoint with a bounded interval until approval, denial, expiry, or cancellation.
  18. Store the approved credential in the operating-system credential store.
  19. Store only non-secret context configuration in the dygo Control config file.
  20. Call the current-user endpoint with the new credential.
  21. Print the context, server, authenticated user, and a successful connection result.

Example terminal flow:

$ dygoctl setup

Deployment URL: https://erp.example.com
Context name [erp-example]:

Open this page to authorize dygo Control:
https://erp.example.com/cli/authorize

One-time code: HAPY-DYGO

Waiting for authorization...

Connected.
Context: erp-example
Server:  https://erp.example.com
User:    operator@example.com

Setup options

Support options that keep the wizard scriptable without bypassing human authorization:

dygoctl setup --url https://erp.example.com
dygoctl setup --context erp-production
dygoctl setup --no-browser

Do not add a password flag. Do not accept a password through command history or a config file.

Automation uses a service account or token flow defined with #70. It does not automate a human browser session.

Existing contexts

If the context already exists:

  • show its current URL;
  • refuse a silent replacement;
  • ask before changing the URL;
  • revoke or preserve the old credential according to the operator's explicit choice;
  • never send an existing credential to a newly entered host before the host is confirmed.

Authentication model

Use browser-assisted device authorization for human operators.

Studio already owns interactive user authentication. The CLI must reuse that surface so password, MFA, SSO, and future identity-provider rules stay in one place.

The CLI credential must:

  • be an opaque random value;
  • be stored only as a digest on the server;
  • be stored in the operating-system credential store on the client;
  • use Authorization: Bearer for API requests;
  • identify its user, context, credential type, and device name;
  • have creation, expiry, last-used, status, and revocation data;
  • inherit the user's roles and Permissions;
  • support narrower access without granting access that the user does not have;
  • be individually visible and revocable through the dedicated session surface from Add dedicated session management surface #73;
  • never appear in Logs, errors, shell output, Activity, Audit Logs, or the non-secret context file.

Device authorization requests must:

  • expire quickly;
  • use a one-time human-readable code;
  • bind approval to the correct deployment and requesting client;
  • rate-limit public initiation and polling endpoints;
  • stop polling after approval, denial, expiry, terminal cancellation, or a bounded timeout;
  • prevent reuse after completion;
  • record safe security events for request, approval, denial, use, and revocation.

Add a Studio route such as /cli/authorize. An unauthenticated visitor must pass through /login and return to the pending request. The approval page must show the deployment, user, CLI name, requested access, creation time, and expiry.

Context and credential commands

dygoctl context list
dygoctl context add <name> --url <url>
dygoctl context use <name>
dygoctl context show
dygoctl context remove <name>

dygoctl auth login
dygoctl auth whoami
dygoctl auth logout

dygoctl health
dygoctl version
dygoctl capabilities

Use context for a remote deployment. Do not reuse the existing --env meaning. The framework CLI uses environment names to select local project configuration.

Planned operator command surface

Users, roles, and sessions

dygoctl user list
dygoctl user show <user>
dygoctl user invite <email>
dygoctl user enable <user>
dygoctl user disable <user>

dygoctl role list
dygoctl role show <role>
dygoctl role assign <role> --user <user>
dygoctl role revoke <role> --user <user>

dygoctl session list
dygoctl session revoke <session>

These commands depend on the purpose-built management APIs from #73 and #74. Do not grant generic access to sensitive session Records.

Business Records

dygoctl record list crm/contact
dygoctl record show crm/contact CNT-00042
dygoctl record create crm/contact --data contact.json
dygoctl record update crm/contact CNT-00042 --set status=active
dygoctl record delete crm/contact CNT-00042

Use the normal Record API and permission engine. Support filters, sorting, pagination, selected Fields, structured input, stable output, and idempotency for retryable writes.

Jobs and Schedules

dygoctl job list
dygoctl job show crm/send-welcome

dygoctl job execution list
dygoctl job execution show <execution>
dygoctl job execution run crm/send-welcome --payload payload.json
dygoctl job execution retry <execution>
dygoctl job execution cancel <execution>

dygoctl schedule list
dygoctl schedule show <schedule>
dygoctl schedule enable <schedule>
dygoctl schedule disable <schedule>
dygoctl schedule run <schedule>

Operational visibility

dygoctl log list
dygoctl log show <log>
dygoctl log tail

dygoctl activity list
dygoctl audit list
dygoctl audit show <event>

Later phases can add maintenance-mode controls and other deployment operations after the server has safe, explicit APIs for them.

Output and automation contract

The operator CLI must support:

  • concise human-readable tables by default;
  • stable JSON output for scripts and agents;
  • consistent pagination controls;
  • documented exit codes;
  • request and correlation identifiers when the server supplies them;
  • stdout for command results;
  • stderr for prompts, warnings, progress, and diagnostics;
  • no ANSI formatting when output is not a terminal or when color is disabled;
  • redaction of credentials, secrets, protected Fields, and sensitive session data.

Do not implement a local-only dry run for remote writes. A remote --dry-run is valid only when the server returns the authoritative plan and applies the same Permission checks as the real operation.

Write safety

Before a material or destructive write, show:

Context: erp-production
Server:  https://erp.example.com
Actor:   operator@example.com
Action:  Disable user user@example.com

Require confirmation unless an approved non-interactive contract exists. --yes can skip a prompt, but it cannot bypass authentication, Permissions, server validation, protected-environment rules, or an unavailable authoritative plan.

Every material write must produce the same Activity or Audit Log evidence as the equivalent Studio action.

Initial delivery phases

Phase 1: foundation and setup

  • Add the dygoctl binary and operator CLI root.
  • Add context storage and selection.
  • Add public deployment discovery and capability checks.
  • Add dygoctl setup.
  • Add browser-assisted device authorization.
  • Add operating-system credential storage.
  • Add auth login, auth whoami, auth logout, health, version, and capabilities.
  • Add stable table and JSON output foundations.

Phase 2: operator visibility

  • Add redacted session commands.
  • Add Logs, Activity, Audit Log, health, and Job Execution inspection.
  • Add Record list and show commands.

Phase 3: controlled operations

  • Add Record writes.
  • Add Job run, retry, and cancel.
  • Add Schedule enable, disable, and run.
  • Add user and role management after Add Studio user and role management #74 provides canonical service APIs.

Phase 4: deployment administration

  • Design maintenance mode and other privileged deployment APIs.
  • Keep raw SQL, secret-value retrieval, direct database access, process restart, database drop, schema prune, and remote migration out of scope until each operation has a reviewed server-side safety contract.

Acceptance criteria for the foundation issue

  • dygoctl builds as a separate binary from this repository.
  • dygoctl works without a dygo project checkout or local database configuration.
  • dygoctl setup collects and validates a deployment URL.
  • Setup verifies server identity, version, and capabilities before authentication.
  • Setup creates or updates a named remote context without silently replacing an existing target.
  • Setup opens Studio for browser-assisted authorization and provides a manual URL and one-time code fallback.
  • Studio returns the user to the CLI approval page after login.
  • The authorization request expires and cannot be reused.
  • Approval creates an individually revocable CLI credential.
  • The server stores only a credential digest.
  • The client stores the raw credential in the operating-system credential store.
  • The context file contains no raw credential or password.
  • auth whoami proves the selected context and authenticated user.
  • auth logout revokes the current CLI credential and removes its local copy.
  • CLI requests use the same Permission engine as Studio and other HTTP clients.
  • Material writes identify the context, server, actor, and action before confirmation.
  • Sensitive values do not appear in stdout, stderr, Logs, errors, Activity, or Audit Logs.
  • Human output and JSON output have defined, stable contracts.
  • Client and server incompatibility fails with an actionable upgrade message.
  • Documentation explains installation, setup, contexts, authentication, output, logout, revocation, and recovery.

Non-goals for the first phase

  • Do not move the operator CLI into a separate repository.
  • Do not merge the operator command tree into the existing local project command tree.
  • Do not support direct database connections.
  • Do not accept passwords through flags, environment variables, or config files.
  • Do not expose raw session Records or token digests.
  • Do not add raw SQL, database drop, schema prune, secret reveal, deployment restart, or remote migration commands.
  • Do not duplicate Studio's authentication, Permission, Activity, or Audit Log logic inside the CLI.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions