Files
ccs/docs/dashboard-auth-cli.md
T
Tam Nhu Tran bfb8782c15 docs(dashboard-auth): clarify remote setup guidance
- document that CCS ships no default dashboard credentials

- note the new remote setup state and login surface improvements
2026-04-06 17:01:49 -04:00

7.2 KiB

Dashboard Authentication CLI

Last Updated: 2026-04-06

CLI commands for managing CCS dashboard authentication.

Overview

The CCS dashboard (ccs config) can be protected with username/password authentication. This is useful whenever the dashboard is reachable from another device, including when the runtime's default bind is network-accessible or when you explicitly bind it beyond loopback with ccs config --host 0.0.0.0.

Authentication is disabled by default for backward compatibility. Use the CLI to configure and enable it.

CCS does not ship a default dashboard username or password. When someone opens the dashboard from a non-loopback/IP address before auth is enabled, the UI now shows a setup state instead of an ambiguous login form. The host owner must run ccs config auth setup, or the user should switch back to the localhost URL if they are on the same machine.

When auth stays disabled, CCS now applies a localhost-only fallback on sensitive management endpoints. Remote devices can still open the dashboard UI when you intentionally bind it beyond loopback, but write-capable routes such as AI Provider management and CLIProxy auth/status helpers reject non-loopback requests until you enable dashboard auth.

Dashboard auth and account context metadata are separate:

  • dashboard_auth: protects dashboard access with username/password
  • accounts.<name>.context_mode/context_group: controls isolated vs shared account context

Account context is isolation-first:

Mode Default Requirement
isolated Yes No context_group required
shared No (opt-in) Valid non-empty context_group

Shared continuity depth:

  • standard (default): shares project workspace context only
  • deeper (advanced opt-in): also syncs session-env, file-history, shell-snapshots, todos

context_group normalization and validation:

  • trim + lowercase + collapse internal whitespace to -
  • allowed characters: lowercase letters, numbers, _, -
  • must start with a letter
  • max length: 64
  • shared mode requires non-empty value after normalization
  • continuity_mode is only valid when mode is shared

PUT /api/config behavior for account context:

  • rejects invalid unified payloads
  • rejects explicit context_mode: shared with invalid/empty context_group
  • rejects invalid continuity_mode values
  • normalizes valid shared context_group before save
  • defaults missing shared continuity_mode to standard
  • rejects context_group when mode is not shared
  • rejects continuity_mode when mode is not shared

Dashboard accounts context editing:

  • PUT /api/accounts/:name/context updates context mode/group/continuity for existing auth accounts
  • rejects CLIProxy OAuth account keys for this route
  • applies normalization/validation rules above

Commands

ccs config auth setup

Interactive wizard to configure dashboard login.

$ ccs config auth setup

╭─────────────────────────────────╮
│  Dashboard Auth Setup           │
╰─────────────────────────────────╯

[i] Configure username and password for dashboard access.
    Password will be hashed with bcrypt before storage.

Username
Enter username: admin

Password
    Minimum 8 characters
Enter password: ********
Confirm password: ********

[i] Hashing password...

[OK] Dashboard authentication configured

[i] Settings saved to ~/.ccs/config.yaml
[i] Username: admin
[i] Session timeout: 24 hours

    Start dashboard: ccs config
    Show status: ccs config auth show
    Disable auth: ccs config auth disable

ccs config auth show

Display current authentication status.

$ ccs config auth show

╭─────────────────────────────────╮
│  Dashboard Auth Status          │
╰─────────────────────────────────╯

Configuration
[OK] Authentication: Enabled
[OK] Username: admin
[i] Session timeout: 24 hours

Commands
  ccs config auth setup     Configure authentication
  ccs config auth disable   Disable authentication
  ccs config                Open dashboard

ccs config auth disable

Disable dashboard authentication with confirmation.

$ ccs config auth disable

╭─────────────────────────────────╮
│  Disable Dashboard Auth         │
╰─────────────────────────────────╯

[!] This will disable login protection for the dashboard.
[i] Anyone with network access will be able to view the dashboard.

Disable authentication? [y/N]: y

[OK] Dashboard authentication disabled

[i] Credentials preserved - re-enable with: ccs config auth setup

ccs config auth --help

Display usage information.

Environment Variables

Environment variables override config.yaml values:

Variable Description
CCS_DASHBOARD_AUTH_ENABLED Enable/disable auth (true/false)
CCS_DASHBOARD_USERNAME Username
CCS_DASHBOARD_PASSWORD_HASH Bcrypt password hash

Generating a Password Hash

Use bcrypt to generate a hash:

# Using Node.js
node -e "console.log(require('bcrypt').hashSync('your-password', 10))"

# Using npx
npx bcrypt-cli hash "your-password"

Configuration

Settings are stored in ~/.ccs/config.yaml:

# Dashboard Auth: Optional login protection for CCS dashboard
# Generate password hash: npx bcrypt-cli hash "your-password"
# ENV override: CCS_DASHBOARD_AUTH_ENABLED, CCS_DASHBOARD_USERNAME, CCS_DASHBOARD_PASSWORD_HASH
dashboard_auth:
  enabled: true
  username: "admin"
  password_hash: "$2b$10$..."
  session_timeout_hours: 24

Security Notes

  1. Bcrypt hashing: Passwords are hashed with bcrypt (10 rounds) before storage
  2. Session cookies: Sessions use HTTP-only cookies (not accessible via JavaScript)
  3. Rate limiting: Login attempts are rate-limited (5 per 15 minutes)
  4. Fail-closed remote writes: When auth is disabled, sensitive management routes allow localhost only
  5. File permissions: Config file is created with 0o600 permissions

Troubleshooting

"Authentication not configured"

Run ccs config auth setup to configure credentials.

Forgot password

Run ccs config auth setup again to set a new password.

ENV override not working

Ensure the variable is exported:

export CCS_DASHBOARD_AUTH_ENABLED=true
export CCS_DASHBOARD_USERNAME=admin
export CCS_DASHBOARD_PASSWORD_HASH='$2b$10$...'

Session expired immediately

Check session_timeout_hours in config. Default is 24 hours.

"Invalid ... context_group ..."

This error comes from PUT /api/config when an account explicitly sets shared mode with an invalid group. Use a canonical group value (for example: team-alpha).

See Also