Skip to content

Console phase 4: testing each step

The phase 4 plan builds provisioning in steps. Each step ends in a test on lite-dev before the next starts. This page holds those tests, one section per step, added as each step is built.

Step 1: History and job requests

What it adds: the Provisioning page (in the top bar, beside History) with the four v1 jobs, each form built from its definition in console/jobs/, and the Jobs and changes section of History. A request is checked against its definition, stored once and recorded. Nothing is approved or run: approval needs the passkey step-up (step 2) and running needs the runner (step 4).

  1. Merge to main and run the console playbook from octo-ctl, as in Console first light. It runs migration 0005 (the jobs and history tables).

  2. The app role may only read and insert, on lite-dev:

    sudo docker exec registry psql -U console_owner -d registry -c '\dp jobs' -c '\dp history'
    

    Each shows console_app=ar/console_owner: a insert and r select, no w (update) or d (delete).

  3. On the Console, open Provisioning, then Create tenant:

    • Slug lite-dev: refused, A tenant with this slug already exists, and nothing is listed.
    • Slug -x: refused against the slug field.
    • Slug sandbox2, display name Sandbox two: listed under Requests as Waiting for approval, with your address and the time.
    • Slug sandbox2 again with any other display name: refused on the slug field, A request to create this tenant is already waiting (#n).
    • Display name s: refused, At least 3 characters.
  4. Withdraw it: it shows Withdrawn. History shows both rows (Requested create-tenant and Withdrew job), with who, when, the tenant sandbox2 and Main.

  5. Add mailbox for lite-dev with admin.octopodia@gmail.com: refused, This tenant already has that mailbox. With two addresses separated by a comma: refused, One email address. A new address, say test@example.com.au, is accepted; the same address again, for any tenant, is refused, A request to add this mailbox is already waiting (#n). Withdraw it.

Requests made here stay in History for good; withdraw the ones you made while testing.

Step 2: passkeys and approval

What it adds: a Passkeys page (/passkeys, in the top bar beside Provisioning and History), enrolment under a 15-minute permission, and Approve with passkey on each waiting request. An approval is a passkey check with its PIN or fingerprint, bound to that request's ID and the hash of its inputs (ADR-0040 ยง4). Still nothing runs: the runner is step 4. Passkeys belong to the Console's address (console_public_url, today console.octopodia.com.au); when lite-dev moves to console-dev.octopodia.com.au you enrol again there.

  1. Merge to main and run the console playbook. It runs migrations 0006 (passkeys, their uses and revocations, challenges, approvals) 0007 (passkey names) and 0008 (job turns: an approved job is either claimed by the runner or cancelled, never both), and sets CONSOLE_PUBLIC_URL.

  2. The app role may only read and insert the new tables, on lite-dev:

    for t in passkey_grants passkeys passkey_revocations passkey_uses webauthn_challenges webauthn_challenge_uses approvals passkey_names job_turns; do
      sudo docker exec registry psql -U console_owner -d registry -tAc "\dp $t" ; done
    

    Each line shows console_app=ar/console_owner.

  3. Your first passkey, from the host (nobody has one yet to vouch for you):

    sudo docker exec console python -m app.cli passkey-invite --operator el@octopodia.com.au --admin "$USER@$(hostname)"
    

    Within 15 minutes, on the Console's Passkeys page: name it YubiKey and enrol your YubiKey (it asks for the key's PIN and a touch), then name and enrol your device passkey. A third is refused. History shows the break-glass permission and both enrolments.

  4. Approve. Request Check host for lite-dev, then Approve with passkey: the browser asks for a passkey, then its PIN or fingerprint. The request shows Approved, waiting for the runner, cannot be withdrawn, and History shows Approved with which passkey.

  5. Rename a passkey on the Passkeys page (YubiKey to Blue YubiKey, say). The new name shows at once; History shows Passkey renamed with the old and new names. A name one of your other passkeys already has is refused. Renaming needs no passkey check: a name only tells your passkeys apart, and the approval records which passkey signed.

  6. Refusals worth seeing once:

    • Start an approval and cancel the passkey prompt: cancelled or timed out. Nothing was approved.
    • Revoke one of your passkeys on the Passkeys page; it no longer approves. (Enrolling a replacement needs Lachlan's Let them enrol, or passkey-recover, so do this last, or re-run passkey-recover to enrol two fresh ones.)
  7. Cancel the leftover test approvals: the first use of Cancel. Each Approved, waiting for the runner request has a Cancel button. Its confirm step names the job and its inputs; either operator may cancel, with no passkey check (it only stops something from running). The request shows Cancelled after approval and moves behind Show withdrawn and cancelled; History adds Cancelled after approval with who and when, after the untouched Approved entry. The same Check host can then be requested again, which is how a second approval test is done with one tenant. Before cancelling, a repeat request is refused with The same request is already approved (#n). Cancel it first to send a new one.

Withdraw any test requests you leave waiting, and cancel any approvals: nothing runs them until step 4, and an approval still waiting when the runner arrives could be picked up by it.