Skip to content
Getting started

Getting started

This page takes you from the sign-in screen to a first reading of the Overview page. It describes the console as the code in this repository builds it.

Where the console runs

The CORE console is not a separate service. It is an HTTP server inside the core-operator process (grpc/operators/core/internal/console), on every replica. It serves:

  • the Flutter web app from CONSOLE_WEB_DIR (with an HTML fallback page when that is unset);
  • the JSON API under /api/* and the sign-in routes under /auth/*;
  • gRPC-web for the Atlas, Ask and shared-UI services, on the same origin and the same session.

CORE is deployed per client installation, so each installation has its own console URL. The CLI has no default console URL for the same reason: --console-url (or CORE_CONSOLE_URL) is set per installation.

Step 1: sign in

The console offers the sign-in methods that are configured. GET /api/me tells the web app which ones to show (googleAuth, passwordAuth, authRequired).

MethodTurned on byNotes
GoogleGOOGLE_CLIENT_IDThe ID token is verified locally against the issuer’s keys. The issuer is https://accounts.google.com unless OIDC_ISSUER overrides it. The email must be verified.
Username and passwordCONSOLE_ADMIN_PASSWORDThe user name is CONSOLE_ADMIN_USERNAME, default admin. Compared in constant time.
reCAPTCHA (optional)RECAPTCHA_SITE_KEY, RECAPTCHA_API_KEY and a project idChecked before the credential when all three are set.

Who may sign in is decided by CONSOLE_ALLOWED_EMAILS (a list) or CONSOLE_ALLOWED_HD (a hosted domain). When neither is set, every Google sign-in is refused. The check fails closed on purpose (emailAllowed in auth.go).

If neither GOOGLE_CLIENT_ID nor CONSOLE_ADMIN_PASSWORD is set, the console runs open: no sign-in screen, every read works. Privileged writes are then refused, because nobody can be named in the audit trail. Each refusal says so, for example “this console has no sign-in configured, so an Atlas CapEx change would be unattributable”.

Sessions are server-side. The cookie core_console_session holds an opaque session id; the session itself lives in the console’s own encrypted store and lasts 12 hours. Log out (/auth/logout) revokes it on the server.

Step 2: choose an instance

After sign-in the console shows landing cards: one per instance (ClientInstance) you hold a live grant on, read from the shared profile service. Choosing one tells the console which instance to act for. The choice is kept in the browser (or in ?instance=<id>), and the server is never told: every admin call names the instance and is checked again on the server.

You can continue without an instance. A ?tab= deep link also skips the landing cards.

The Admin row (DataEx › Trust › Admin) appears in the rail only when the server reports that you are an admin of the chosen instance. This is a display rule only: every access call checks the role again.

Step 3: learn the rail

The rail has five categories, in this order:

CategoryQuestion it answers
OverviewIs anything wrong, and where do I go next?
DevExWhat is deployed, how traffic reaches it, whether the record of every action is intact, and what the agents did.
DataExWhich models serve, which agents act and under what limits, which sources CORE reads and what reads them, and who may do what.
IntelligenceWhat the platform knows about the data estate (the Atlas pages, Resolve, Data audit), plus whether a commit shipped (Deploy lineage).
FORGEWhat is being built: FORGE’s chats, opened in the Studio.

Account and Log out are in the rail footer. Below a window width of 720 px, the rail moves into a drawer. See the console map for every page.

Every page can be linked with ?tab=<name>, for example /?tab=gitops. There is one route, and the URL does not change as you move around. An unknown name opens Overview; a retired name opens the page that now owns its subject.

Step 4: read the Overview page

Read it from top to bottom:

  1. The header. The pill says {healthy}/{total} healthy for the workloads the console tracks (Deployments and DaemonSets in core-system, runink-system, pulse-system, luna-system, forge-system, inference-system, github-runners and registry-system). The header also names its source (kube-api) and the time of the data. If the dashboard read failed, a red notice gives the reason and the source is marked absent.
  2. The KPI strip. Client instances (ready and not suspended, out of all), Workloads (healthy out of total), Agent runs (7d) and Success rate. An empty instance list is shown as neutral, not green: nothing to judge is not a pass.
  3. Needs attention. The open findings from Trust › Harness, worst first, each with a link to act on it.
  4. Recent agent runs. The eight newest runs, with the freshness of the run store stated above them.
  5. Platform. One line each for workloads, instances, inference and data sources, each linking to its page.
  6. Ask CORE. The orchestration chat (see below).
The agent-run tiles need the CORE GitHub App. Without it they show “—” and the sentence “Install the CORE GitHub App to show agent-run status + logs here. It needs actions:read; the console mints a short-lived installation token itself.” That is a missing configuration, not zero runs.

The Success rate is success ÷ (success + failure). Runs that are still running or were cancelled count in the total but not in the rate. When no run has finished, the tile shows “—”.

Step 5: ask CORE

The chat box sends POST /chat {"message": "..."}. The console’s model turns the sentence into exactly one tool call (chat.go):

  • read tools such as list_client_instances and reply run at once;
  • the one mutating tool, create_client_instance, is proposed, not run. You get the exact action and arguments back with a one-time code, and nothing happens until you send confirm <code>. The code is bound to you, single-use, and expires after 5 minutes. The CONSOLE_INSTANCE_ADMINS allowlist is checked again when you confirm.

What you type, and what the model answers, pass through the console’s guardrail before the model sees the input and before you see the output. A blocked message returns 403 with the guardrail’s wording.

The speaker and microphone buttons appear only when the voice services are wired: TTSD_URL for speech output and VOICE_REMOTE_URL for speech input (reported as voiceTts and voiceStt by /api/me).

Next steps