corectl
corectl is the command-line client for the Core Platform API. Core Platform Portal
(or Portal) is the web client of the same API. The client supports login, context
selection, cluster listing, agent lifecycle operations and kubeconfig generation.
Human connections use existing local Kubernetes credentials; GitHub Actions can
use --oidc github to obtain renewable short-lived Pinniped credentials through
a private tunnel. Application creation is not currently supported by the CLI.
Install
corectl supports macOS on Apple Silicon and Linux on ARM64 or x86_64.
Trust the Core Platform Homebrew tap and install coreplatform to get corectl,
the Core Platform CLI tool, and its dependencies:
brew trust coreeng/public
brew install coreeng/public/coreplatform
corectl versionSee Updating corectl to upgrade an existing installation.
Download a specific version manually
Releases are published as public packages at ghcr.io/coreeng/corectl.
corectl has its own release versions and production promotion, independent of the
Core Platform API, Portal and agents. Use a production-promoted corectl version in place of VERSION
below. The Homebrew formula
records the currently promoted version.
PR previews carry a commit SHA suffix; merges publish versioned release candidates.
Both are public after successful corectl checks, so you can use them in the same
download command without waiting for production promotion. Promotion selects an
existing tested candidate without rebuilding it. The Core Platform API and Auth
services must support the native CLI before login is available.
With ORAS installed, download the package without a GitHub account:
oras pull ghcr.io/coreeng/corectl:VERSION -o corectl-download
cd corectl-downloadVerify the downloaded files before extracting them:
# macOS
shasum -a 256 -c checksums_VERSION.txt
# Linux
sha256sum -c checksums_VERSION.txtChoose darwin_arm64 for an Apple Silicon Mac, or linux_arm64 / linux_x86_64
for Linux. For example, on an Apple Silicon Mac:
tar -xzf corectl_VERSION_darwin_arm64.tar.gz
./corectl version
./corectl auth login
./corectl get clustersAdd the directory containing the extracted binary to your PATH. The examples below use corectl. Compatible CLI
and API releases can differ, allowing one CLI to work with production and integration.
Updating corectl
For Homebrew installations, run brew update && brew upgrade corectl. For manual
installations, download the new version,
verify its checksums and replace the binary in your PATH. Confirm with corectl version.
After a successful eligible command, corectl can show one stderr notice:
corectl 1.5.0 is available (installed: 1.4.0). Update: https://docs.coreplatform.io/reference/corectl/#updating-corectlChecks read the published Homebrew formula ; Homebrew need not be installed. Checks and notices are limited to once per 24 hours. Lookups run alongside commands with a 200 ms network budget; successful commands wait only for any remaining lookup time. Failures are silent and never change the command’s output or exit status. Nothing is installed automatically.
Checks require interactive stdin, stdout and stderr. CI, --non-interactive,
machine-readable output, help, version, completion and local inspection stay quiet.
Set CORECTL_NO_UPDATE_CHECK=1 to disable checks and notices; use it or
--non-interactive in scripts that inherit a terminal.
Install and manage cluster agents
In a native Context, register the cluster in Portal and choose an existing cluster
or a new local cluster, then copy its suggested corectl agent install command. The Portal URL is optional
for the hosted service at https://portal.coreplatform.io. Include --url the
first time you connect to another Core Platform instance:
Legacy Contexts offer only existing-cluster connection in the Portal. To try Core Platform Local, select a different, native Context.
corectl agent install customer-dev --context core-platform/engineering
corectl agent install customer-dev --context example-platform/engineering --url https://portal.example.com
corectl agent install local-trial --context example-platform/engineering --url https://portal.example.com --create-localYour account needs administrator access in the selected Portal context and sufficient
Kubernetes permissions to manage the Cluster System release, including its namespace and
RBAC. For an existing cluster, provide a working kubeconfig. corectl prompts you to
choose a Kubernetes context if it has no saved association; pass --kube-context
to select one directly. --create-local uses k3d, included in the Homebrew
coreplatform package, and requires a running Docker runtime.
The local cluster uses the Portal registration name and installs both Runtime and
Control agents. corectl embeds Helm and Kubernetes clients;
you do not need Helm or kubectl installed. Any authentication helper referenced by your
kubeconfig, such as a cloud credential plugin, must still be available and authenticated.
corectl does not provision cloud credentials or Kubernetes access. Kubernetes API
endpoints must use HTTPS, except for localhost and loopback IP addresses. Server URLs
must not contain embedded credentials, query parameters, or fragments.
--kubeconfig PATH selects a configuration file; otherwise corectl uses KUBECONFIG
or ~/.kube/config. The initial interactive command asks you to choose a Kubernetes
context when --kube-context is omitted. Noninteractive runs need an explicit context
or an association saved by a previous successful operation. corectl never changes your
kubeconfig’s current context.
Portal commands include --context CONTEXT_NAME, using the full context key
from login, for example:
corectl agent upgrade customer-dev --context core-platform/engineering-testThis selects the intended Core Platform context for that command without changing your
saved selection. --context is separate from --kube-context, which identifies the
Kubernetes cluster. Release ownership checks use immutable internal identities.
After a successful operation, corectl remembers the nonsecret Kubernetes context and kubeconfig path for that instance, context and cluster on your computer:
corectl agent enable-management customer-dev
corectl agent upgrade customer-dev
corectl agent repair customer-dev
corectl agent uninstall customer-devinstallinstalls or re-enrolls the Runtime Agent.enable-managementinstalls or re-enrolls the Control Agent. A fresh Runtime Agent is required. corectl performs both managed bootstrap stages when needed.upgradeuses the version selected by Portal and preserves agent credentials.repairrestores a missing or broken release using fresh enrollment tokens for all agents required by the cluster’s current mode. Context resources are preserved.uninstallremoves the Cluster System Helm release and waits up to five minutes for chart resources to be deleted. If deletion fails or times out, fix the reported issue and retry; corectl retains the release history and local association. Portal registration and context resources remain; disconnect the registration separately in Portal.
corectl checks Kubernetes access and existing release ownership before requesting enrollment tokens. Tokens are obtained at execution time and are not included in copied commands or corectl’s local metadata. The installed Helm release and chart-managed Secrets retain the same credential behavior as a manual Helm installation. Portal shows enrollment progress and confirms a fresh agent report.
If an operation fails, corectl reports the stage that failed. Fix the reported access or
release issue and retry; use repair when the release or credential Secrets are missing.
Interrupted or failed Helm operations may leave a release requiring inspection before
retrying. There is no automatic rollback of enrollment credentials.
Before disconnecting a registration, retain Portal’s cleanup command. It works after the registration is deleted and does not need a Portal login:
corectl agent uninstall --release-name cp-0123456789abcdef01234567 --kube-context my-kubernetes-contextPublished charts can be installed on any reachable Kubernetes cluster, including k3d,
using its existing kubeconfig. Source-built chartVersion=local instances continue to
use the repository’s local Make and image-import workflow.
Sign in and list clusters
corectl auth login
corectl get clustersLogin opens a browser on your machine and uses portal.coreplatform.io by default.
Sign in and approve access for corectl, even if your browser is already signed in.
You can decline without changing your saved contexts. After browser sign-in, the
corectl next steps page opens. Return to your terminal
for confirmation that the API accepted your login and credentials were saved.
The confirmation shows the context key followed by the readable context name:
Logged in to core-platform/engineering-test (Engineering Test) as user@example.comAn additional Current context: ... line appears only when your saved default
context differs from the context you just signed in to. For example, signing in
with corectl auth login --context CONTEXT_NAME preserves your saved default
and reports it separately when it differs.
If you have one context, it is selected automatically. Most users can continue
with get clusters without managing contexts. Check your identity with
corectl auth whoami, or sign out with corectl auth logout.
auth whoami shows the effective context key, context display name and account:
CONTEXT DISPLAY NAME USER
core-platform/engineering-test Engineering Test user@example.comIts JSON and YAML output include context, displayName, instance and user. Context overrides apply to that
invocation without changing the saved current context.
Tokens are stored in macOS Keychain or Linux Secret Service and refreshed automatically. On Linux, an unlocked Secret Service session must be available; tokens are never stored as plaintext files.
If browser opening fails, corectl prints the URL so you can open it yourself.
Use corectl auth login --no-browser to always print the URL without opening it.
Open it in a browser on the same machine: the callback uses a local loopback port.
This is not a remote-shell device login flow.
If login cannot start, corectl reports the instance URL and HTTP status. Check that you selected the intended instance; if the problem persists, share the error with your platform team. Deleting local credentials does not fix this error.
Output formats
get clusters, get tunnels, config get-contexts, and auth whoami display tables by default and
support -o json and -o yaml for structured output:
corectl get clusters -o json
corectl config get-contexts -o yaml
corectl auth whoami -o jsonCluster tables use NAME, TIER, VERSION, TYPE, REGION, and STATUS, in that
order. Cluster listing follows the same context visibility as Portal, including
catalogue entries without a connected agent. Type and region come from the API;
unavailable values are displayed as -. Reported cluster IDs remain available in
JSON/YAML under clusterRuntime.clusterId and clusterControl.clusterId.
VERSION shows the version reported by the configured agents. It is Mixed
when fresh Runtime Agent and Control Agent reports disagree, and Unknown when a
configured agent has no fresh version report. The value comes from Portal; listing
clusters does not require kubeconfig access or contact the Kubernetes cluster.
Tables shorten trailing full commit hashes to five characters, matching Portal.
JSON and YAML retain full versions and include platformRegion, installedVersion and each available agent’s agentVersion
and heartbeat freshness under clusterRuntime and clusterControl.
Above a cluster table, corectl identifies the effective destination:
Context: core-platform/engineering-test (Engineering Test)This line reflects command overrides and is written to stderr. JSON and YAML
include context, displayName and instance in the output instead of this heading.
Diagnostic output
The global -v / --verbose flag adds diagnostic details on stderr. For agent
operations, these include chart versions, Helm stages, release identifiers and
confirmation that connection metadata was captured and published. The flag works
before or after the command:
corectl -v agent upgrade customer-dev
corectl agent repair customer-dev --verboseCommand results stay on stdout. Verbosity does not change the result data or
format, so -o json and -o yaml remain valid structured output. To save results
without diagnostics, redirect stdout separately:
corectl --verbose get clusters -o json > clusters.jsonWithout --verbose, agent commands show concise progress and results. Warnings,
prompts and recovery instructions are always shown. Agent operations still identify
the selected Kubernetes target, and offline uninstall always identifies its release.
Work with multiple contexts
If you belong to multiple contexts, list them and select where to work:
corectl config get-contexts
corectl config use-context core-platform/engineering-test
corectl get clustersSelection uses the full context key, such as core-platform/engineering-test.
Display names such as Engineering Test are labels, not command selectors.
Switching confirms the exact context key and display label:
Switched to context "core-platform/engineering-test" (Engineering Test).Selecting a context may open Auth in your browser to obtain its credentials. If a script needs a context with no usable credentials, it fails with a login command. An unavailable context never silently falls back to another one.
To use another context for one command without changing the saved default:
corectl get clusters --context core-platform/engineeringCURRENT markers in context tables identify the saved default,
even when a resource command uses an override. To print just the saved context key:
corectl config current-contextWork with additional instances
A context selects where you work in a Core Platform instance. Most users only
need the hosted service. If you have access to another instance, sign in using
its URL, then use the context names printed by get-contexts:
corectl auth login --url https://portal.example.com
corectl config get-contexts
corectl config use-context core-platform/engineering-test
corectl get clusters --context example-platform/engineering-testThe URL and context names above are examples; use those supplied for your instance.
Instances retain separate credentials. config use-context saves a new default.
Resource-command --context overrides apply to that invocation only. Login normally
selects the context you signed in to. An explicit
auth login --context CONTEXT_NAME signs in to that context while preserving
the saved default. On first login, when there is no default, the authenticated
context becomes the default.
To bootstrap a specific context in a new instance, supply both its URL and key:
corectl auth login --url https://customer.example.com --context customer/engineeringThe discovered instance must match customer, and your authenticated memberships
must include engineering. Without --url, an explicit context must already be
known locally; corectl never infers an instance URL from its name.
Context keys and display names come from the latest successful login. Refreshing another context’s older session does not replace them. A new login picks up display-name changes without changing context identity or keys; a short-name change updates the context key.
List saved contexts
corectl config get-contexts
corectl config get-contexts -o wide
corectl config get-contexts --offline --no-headers
corectl config get-contexts -o nameThe listing includes all memberships learned from successful logins, even when a context has no saved credentials. It does not discover unknown instances or new memberships until you sign in again.
The default table has CURRENT, NAME, DISPLAY NAME, and AUTH columns. NAME is
the exact context key; DISPLAY NAME is its readable display name. -o wide adds the
saved account in USER. --no-headers omits headers from default and wide tables.
By default, get-contexts verifies saved logins against each instance and refreshes
tokens only when needed. It never opens a browser or changes your selected context.
Failed checks retain saved credentials. Table labels and structured authStatus
values differ:
| Meaning | Table AUTH | JSON/YAML authStatus |
|---|---|---|
| Login verified | signed in | logged in |
| Credentials missing or rejected | not signed in | login required |
| Verification could not complete | unavailable | unavailable |
| Saved credentials have not been checked | not checked | not checked |
Use --offline to list local metadata without accessing credentials or the network;
saved logins then show not checked. Online checks have a five-second network
timeout per instance, adjustable with --timeout 10s, and check up to four
instances concurrently.
-o name prints only sorted context keys, one per line. It always uses local
metadata, without accessing credentials or the network, and prints nothing when
there are no contexts. -o wide, -o name, and --no-headers are available on
config get-contexts; resource listings retain table, JSON, and YAML output.
Structured context rows include name, current, instance, displayName,
user, credentialsSaved, and authStatus. name is the full context key;
displayName supplies the readable label. credentialsSaved
indicates local storage, not successful authentication. --no-headers does not
apply to JSON, YAML, or names-only output.
Sign out
corectl auth logoutLogout clears all context credentials for the selected instance while retaining
its saved contexts. To select another instance for logout, use
corectl auth logout --context CONTEXT_NAME. If there is no saved login to clear,
it succeeds with Already logged out. Other instances remain signed in.
If remote revocation is unavailable, corectl reports that separately; previously issued access tokens can remain valid until they expire. If instances share the same Auth session, remote revocation is skipped and reported to preserve the other instance’s login. Logout does not modify Kubernetes credentials.
Check the client version
corectl version
corectl version -o json
corectl version -o yamlThe default output is one line, for example:
corectl 0.8.0 (0123456) darwin/arm64 go1.27.0It shows the release version, short source commit, OS/architecture, and Go version.
A local build with uncommitted changes adds -dirty to the commit. Unknown Git tree
state adds -unknown to a known commit; a missing commit is shown as unknown.
JSON and YAML expose version, the full commit, platform, goVersion, and
gitTreeState (clean, dirty, or unknown). Version inspection needs no login
or network access.
Shell completion and help
Homebrew installs bash, zsh and fish completions alongside corectl. With
Homebrew shell completion configured,
open a new shell after installing or upgrading to use them.
For zsh, ensure eval "$(brew shellenv)" runs before completion initialization.
If your shell configuration or framework does not already call compinit, add
these lines to ~/.zshrc after your Homebrew environment setup:
autoload -Uz compinit
compinitHomebrew’s fish discovers the installed completions automatically. Bash needs Homebrew’s bash-completion setup linked above.
For local builds, manual installations, or PowerShell, generate shell completion
code by specifying bash, zsh, fish, or powershell:
corectl completion zshThe generated code must be loaded into your shell to enable completion. For zsh:
autoload -Uz compinit && compinit
source <(corectl completion zsh)See corectl completion --help for current-session examples for the other shells.
Context completion inserts exact selectors with readable display
labels. It reads saved metadata only, without accessing credentials or the network.
Suggestions include all locally known contexts. A supplied auth login --url
filters them to that known destination; an unknown URL has no suggestions until
login discovers its memberships.
--kube-context completes Kubernetes context names from --kubeconfig, the merged
files in KUBECONFIG, or the default ~/.kube/config. It filters by the prefix
you type and does not contact Kubernetes, run credential helpers, or change the
current context. To complete from a specific file, put --kubeconfig PATH before
--kube-context.
Root help lists available commands before usage. Individual command help includes examples and supported flags:
corectl --help
corectl auth login --help
corectl config get-contexts --helpConfiguration storage
On both macOS and Linux, corectl stores its configuration in
~/.config/corectl/config.json. Set XDG_CONFIG_HOME to an absolute directory to
use $XDG_CONFIG_HOME/corectl/config.json instead. Relative values are ignored.
Saved instances, contexts and the selected context live in that file; login tokens remain in the OS credential store.
Authentication security
corectl opens your system browser for Keycloak login and explicit approval. It uses
Authorization Code flow with S256 PKCE and binds refresh tokens to a key stored with
the login in your OS credential store. Refresh and revocation require a DPoP proof;
copying a refresh token alone is insufficient. Logins created before this protection
require corectl auth login again.
Portal authenticates its own token requests with a server-only signing key. Both clients use the same API authorization boundaries, enforced using verified roles and immutable internal Tenant identity. Context selects the instance and customer scope to access; its name and display label do not grant access or determine ownership. Access tokens are still short-lived Bearer tokens; logout prevents further refresh but does not immediately invalidate every issued access token. See the Auth security documentation for the RFC mapping, deployment requirements and limits.
Configure kubectl for a registered cluster
Sign in to Core Platform, then use the cluster’s short name. In Portal, open the cluster and choose Set up kubectl to find the connection command and applicable local credential guidance.
corectl connect gcp-dev --context core-platform/cecgThe command creates and selects Kubernetes context core-platform/cecg/gcp-dev.
--context selects the Core Platform context for this invocation. It does not
select a source Kubernetes context or change your saved Core Platform default.
Qualified cluster arguments such as cecg/gcp-dev are not supported.
You must already have cloud/Kubernetes credentials and network access to the API endpoint directly, or use Core Platform VPN when the cluster has a ready managed connector. Connect verifies TLS and authenticated identity with SelfSubjectReview before writing. Success does not grant additional Kubernetes permissions or guarantee authorization for every subsequent operation.
| Option | Behavior |
|---|---|
--kubeconfig PATH | Write an isolated destination; otherwise use standard KUBECONFIG / ~/.kube/config loading rules |
--no-switch | Preserve Kubernetes current-context |
--proxy-url URL | Use an existing HTTP, HTTPS or SOCKS5 proxy for Kubernetes verification and save it only in the local kubeconfig |
--namespace NAME | Set a namespace; otherwise preserve the existing value |
--timeout 2m | Bound generation and verification |
--non-interactive | Never prompt or initiate login; no TTY also implies this behavior |
--client-certificate PATH --client-key PATH | Use your own local certificate and private key files |
-o json or -o yaml | Print context, destination, selection and verification result without credentials |
Existing unrelated configuration is retained. Same-name entries owned by another
identity or registration are not overwritten. An ambiguous multi-file destination
requires an explicit --kubeconfig. Failed generation or verification leaves the
destination unchanged. Connect does not change administrator installation associations.
If an instance or context rename would rename your selected Kubernetes context,
--no-switch stops without changing kubeconfig. Select another context first, or
retry without --no-switch to rename and select the updated context.
For managed clusters, corectl first verifies direct access. If the network dial fails, it asks Portal to authorize a cluster-scoped VPN session and starts a background worker. TLS and Kubernetes authentication failures do not trigger VPN fallback. The worker exposes an authenticated loopback proxy and keeps the original API endpoint and TLS verification in kubeconfig. Kubernetes credentials are still yours to supply; VPN access does not grant Kubernetes permissions. Portal fixes this human session’s destination to the registered Kubernetes API. The local proxy cannot use it to reach other cluster Services.
corectl connect gcp-dev
corectl get clusters
corectl disconnect gcp-devTo require VPN even when the Kubernetes endpoint is publicly reachable, use:
corectl connect gcp-dev --vpn--vpn skips the direct Kubernetes access check, verifies access through the managed
tunnel, and saves that route in kubeconfig. It fails if VPN access is unavailable;
it never falls back to a direct connection. It cannot be combined with --proxy-url.
This is useful for testing VPN access without changing the cluster’s endpoint.
get clusters groups all local tunnels beneath each cluster. The cluster TYPE
remains separate from tunnel purpose and transport:
NAME STATUS TUNNEL PURPOSE TRANSPORT
dev active Ready Kubernetes Direct
Ready Registry DERP relay
staging active Recovering Kubernetes Unknown
sandbox active — — —Other existing cluster columns are omitted from this example. Dashes mean no
local tunnel was found; unavailable or incomplete worker inspection is reported
explicitly. JSON and YAML contain one cluster object with a tunnels array.
The cluster list still requires Portal.
Use the focused local inventory during a Portal outage:
corectl get tunnels --context core-platform/engineering
corectl get tunnels dev --context core-platform/engineering --verbose
corectl get tunnels dev --context core-platform/engineering -o jsonSESSION CLUSTER PURPOSE STATE TRANSPORT AGE
8c91a20f dev Kubernetes Ready Direct 24m
4eb283ad dev Registry Ready DERP relay 11m
b628a741 staging Kubernetes Recovering Unknown 36mget tunnels inspects authenticated workers in the selected local state directory
without Portal discovery, sign-in, keychain access or a remote probe. It uses the
current saved Context by default; specify --context when none is selected.
It includes human and CI workers in that directory, not other computers or
Portal access gateways. A fresh CI state directory can supply its Context binding
from private worker configuration without a saved human login.
Purpose identifies Kubernetes, Kubernetes via Pinniped, or Registry. Transport is Direct, DERP relay, Peer relay, or Unknown, based on the last observed path to the selected connector peer. The last known transport remains visible while idle or when a later sample is unavailable. Unknown means no path has been observed yet; neither label proves current connectivity. Age is session age, not uninterrupted successful traffic. Verbose diagnostics add the full session ID, last confirmed renewal, acknowledged lease expiry, recovery reason and sanitized local listening endpoint. The ID can correlate CLI output with Portal’s expanded tunnel diagnostics and lifecycle logs.
All managed tunnel purposes share a maximum five-minute lease, capped by the currently verified authentication credential. Active callers refresh credentials and renew before the lease has fewer than three minutes remaining. A transient Portal or broker failure preserves established streams only until their last verified expiry; it does not create new authority. Explicit denial and expiry close access. Healthy renewed tunnels are designed to preserve the same streams through control outages shorter than 60 seconds; relay traffic may pause. Application timeouts, connector/worker/gateway restarts, lost broker identity and expired or revoked authentication remain limits. New sessions need Portal; a new stream whose authorization needs refreshing may be refused during an outage.
connect reuses a matching recovering worker, preserving its local endpoint and
existing streams. Run connect again after the worker expires. Unattended callers
with an existing Core Platform session and local Kubernetes credentials can use
--non-interactive and an explicit --kubeconfig. GitHub Actions jobs use the
dedicated CI connection below.
disconnect stops the local worker and requests revocation, leaving kubeconfig
unchanged. Add --verbose for session duration, purpose, last transport, transport
bytes sent/received and renewal failure/recovery counts:
corectl disconnect dev --context core-platform/engineering --verbose
corectl p2p registry disconnect dev --context core-platform/engineering --verboseStatistics are diagnostic stderr; structured stdout is unchanged. Byte counts include encrypted transport overhead and probes, not just application payload. Unavailable statistics are reported as unavailable. If remote revocation fails, the last locally acknowledged expiry may differ from Portal’s current expiry; remaining remote authority can last up to the five-minute maximum.
Upgrade Portal, broker, connector, gateway and corectl together and reconnect existing sessions. The new purpose/service and listing contracts replace their previous forms; mixed component versions are unsupported.
No system Tailscale client or privileged host network configuration is required.
If Kubernetes access requires a proxy that you already run, supply its local URL:
corectl connect sandbox-aws --proxy-url http://localhost:54882Subsequent kubectl commands use the saved proxy. An explicitly supplied proxy remains caller-managed, and TLS verification remains enabled. The proxy URL is never
uploaded to Core Platform. This option configures Kubernetes access; cloud CLIs and
authentication helpers continue to use their own network configuration. SOCKS5 has
Kubernetes limitations for SPDY streaming operations such as exec, attach and port-forward.
Supply --proxy-url again when reconnecting through that proxy. Omitting it writes
a direct connection when reachable, otherwise using the managed VPN fallback. Normal Kubernetes HTTP/HTTPS environment proxy settings still apply.
Provider requirements
Provider integrations use existing local credentials and installed tools. They do not install tools or run login commands for you.
- GKE:
gcloudandgke-gcloud-auth-plugin; cluster metadata includes project, zone/region and DNS, external-IP or internal-IP endpoint selection. - EKS: AWS CLI;
--aws-profileselects local credentials,--aws-role-arnselects the kubectl authentication role, and--aws-describe-role-arnselects a role used only for retrieving cluster metadata. These choices stay local. - AKS: Azure CLI and
kubelogin, with an existing Azure CLI login to the registered Azure cloud. User credentials are used, never admin credentials. - k3d: on the machine running the cluster, corectl calls
k3d kubeconfig getusing the recorded local cluster name. This reads the cluster’s existing administrator certificate and key and saves them only in your local kubeconfig after verification. The k3d CLI and its local container runtime must be available. Supplying--client-certificateand--client-keyuses those credentials instead and does not call k3d. A localhost endpoint works only on the machine exposing that endpoint. Another machine needs a reachable address whose TLS certificate validates and its own credentials.
Provider endpoint or CA changes require an administrator to refresh metadata. Connect does not silently replace server trust with newly discovered values. GCP remains the production baseline; EKS and AKS are experimental and require validation against the intended provider environment before operational use.
Configure or refresh existing registrations
An administrator with an existing Cluster System installation can backfill public connection metadata without reinstalling agents or rotating enrollment tokens:
corectl agent update-connection-info gcp-dev \
--context core-platform/cecg \
--kube-context existing-admin-contextInstallation capture and agent update-connection-info use any proxy already set
in that source kubeconfig for verification. They publish only cluster endpoint,
TLS trust and provider details. Connecting users can use managed VPN fallback or supply their own proxy through connect --proxy-url.
--kubeconfig on this administrator command selects the source file. Missing
or ambiguous discovery requires explicit provider identifiers. Missing identifiers
for a selected provider can be entered interactively; automation supplies flags.
corectl agent update-connection-info gcp-dev --kube-context renamed-gke-context \
--provider gke --gke-project my-project --gke-cluster gcp-dev \
--gke-location europe-west2 --gke-location-type region --gke-endpoint external
corectl agent update-connection-info eks-dev --kube-context existing-eks \
--provider eks --eks-cluster-arn arn:aws:eks:eu-west-2:123456789012:cluster/eks-dev
corectl agent update-connection-info aks-dev --kube-context existing-aks \
--provider aks \
--aks-resource-id /subscriptions/00000000-0000-4000-8000-000000000001/resourceGroups/platform/providers/Microsoft.ContainerService/managedClusters/aks-dev \
--azure-cloud AzureCloudGKE also supports --gke-endpoint dns and internal, and --gke-location-type zone.
AKS accepts --azure-tenant-id when required by the authentication configuration.
The selected provider locator must reproduce the administrator’s target and trust.
Profiles, client certificates/keys, tokens, local proxy addresses and kubeconfig
contents are never uploaded. A public server CA bundle or explicit system roots
provide trust; insecure TLS is not an option.
New agent installations attempt this capture automatically. If discovery or publication fails, installation still completes and prints the strict backfill command. Existing registrations without metadata remain valid; this is not a cluster health failure. Upgrade the API before deploying the new CLI/UI surfaces. An older API produces an upgrade-required error for connection operations.
Isolated unattended use
corectl connect gcp-dev --context core-platform/cecg \
--kubeconfig ./job-kubeconfig --non-interactive -o json
kubectl --kubeconfig ./job-kubeconfig get podsAn already authenticated Core Platform session and caller-local Kubernetes/cloud credentials are required in this mode. It prepares local configuration for automation and supports the managed Kubernetes VPN described above. For GitHub Actions without local credentials, use the dedicated OIDC flow. Use separate output files for independent jobs.
Upgrade to context-only selection
The Portal and CLI now use Context for your selected place to work. Update the CLI
before copying commands from the updated Portal. The old workspace flag and
commands have been removed without aliases; use --context CONTEXT_NAME,
config get-contexts, and config use-context. JSON/YAML consumers must read the
full selection from context (or name in context-list rows), with its readable
label in displayName. The old workspace output object has been removed. Reload your shell completions after upgrading.
Existing login configuration and saved credentials remain valid. Local agent
installation associations now use format version 2. If corectl rejects an old
installations.json, back it up outside its active path under your corectl config
directory. With the same registered cluster and verified Kubernetes target, run:
corectl agent install CLUSTER --context CONTEXT_NAME \
--kubeconfig EXISTING_KUBECONFIG --kube-context EXISTING_KUBERNETES_CONTEXTThis re-enrols the existing installation and records its new association. It can
renew agent credentials; verify the target before running it. Do not use
--create-local to recover an existing local cluster. Keep its private kubeconfig.
Old generated connection ownership records are not adopted. Reconnect into a fresh destination and use that file explicitly:
corectl connect CLUSTER --context CONTEXT_NAME --kubeconfig NEW_KUBECONFIGReview removal of obsolete generated entries separately. Never delete unrelated kubeconfig entries or recreate resources for this terminology change.
GitHub Actions access through Pinniped
Use OIDC to connect a runner to a cluster’s private Pinniped endpoint. No separate
login, application selector or --non-interactive flag is needed:
corectl connect gcp-pre-prod --oidc github \
--context core-platform/engineering \
--kubeconfig "$RUNNER_TEMP/kubeconfig"--oidc github never prompts, opens a browser or reads human credentials. Use
--url https://your-portal.example for another instance. Portal verifies the
repository’s immutable GitHub owner and repository IDs against a ready application
assigned to that exact cluster. A repository associated with a different cluster
cannot open a tunnel to this one. CI always uses the managed VPN. Portal pins
this session to the private Pinniped impersonation proxy, so the runner cannot
use it to reach an arbitrary Service or the registered raw Kubernetes API.
The command starts a background tunnel, verifies Pinniped-authenticated Kubernetes access, then writes kubeconfig. Helm and kubectl use that tunnel and invoke corectl to obtain fresh short-lived Pinniped certificates when required. The runner cannot use this identity for general Portal queries, configuration or administration. It can resolve deployment targets only for an application associated with its repository:
corectl p2p targets --application payments --oidc github \
--context core-platform/engineering --url https://your-portal.example -o jsonThe response contains fastFeedback, extendedTest and prod matrices.
An authenticated human can run corectl p2p targets --application payments
in a saved context without --oidc. Portal reads each application’s committed
stage assignments, so two applications in one repository can deploy to different
clusters. P2P resolves these targets at run time. When Portal creates an
application repository, it creates the selected GitHub environments and sets
CORECTL_CONTEXT and CORECTL_PORTAL_URL. P2P uses the latest corectl release
unless you explicitly set CORECTL_VERSION on the repository.
Portal does not write repository-wide stage matrix variables.
CI image registry connection
For a CI build, corectl p2p registry connect opens a second session through
the same cluster VPN connector. It can run alongside the Pinniped connection.
Portal checks the GitHub repository and selected application’s assignment to
the cluster, then returns the authoritative organisation-unit/delivery-unit
prefix. The CLI binds the registry to 127.0.0.1:5000 on the runner:
corectl p2p registry connect test-gcp-dev --application payments \
--context core-platform/engineering --url https://your-portal.example \
--ci-environment test-gcp-dev --output envThe CI environment defaults to the cluster ID. Set --ci-environment when the
registry is configured for a different GitHub Actions environment; corectl
checks that value against the job’s GitHub assertion.
The env output contains REGISTRY and P2P_REGISTRY, each set to the full
loopback image prefix. Use it as an environment file in CI. The default JSON
output also contains registry, cluster, prefix, and imageRegistry. Portal fixes this
session’s only destination to the private cluster registry Service. Docker and
Skopeo send registry traffic through the loopback listener; the connector
forwards it without using the Kubernetes API or granting a port-forward
permission. Only one registry connection can bind port 5000 on a runner at a
time.
Set a job-local DOCKER_CONFIG, then run corectl p2p registry login test-gcp-dev --context core-platform/engineering. This authenticates Docker and
Skopeo using a credential scoped to the current local registry connection. P2P
runs login before publishing. For each upstream request, the corectl worker
supplies a cached or automatically renewed GitHub OIDC assertion, so long uploads
can commit after the original assertion expires. Zot checks the job identity and
image path independently of the VPN admission check. The local credential is
never forwarded to Zot and becomes unusable when the worker stops.
Run corectl p2p registry disconnect test-gcp-dev --context core-platform/engineering to close the registry session and remove its isolated
Docker and Skopeo credentials. Reconnect existing registry tunnels after
upgrading corectl.
With the matching managed cluster and P2P releases, kubelets on k3d and GKE Standard pull the same versioned image reference through the platform-managed node proxies. No application imagePullSecrets or containerd changes are needed. See Image registry for the pull path and platform requirements.
The following example sets up Kubernetes access to a fixed cluster. For application-specific deployment targets and image publishing, use the P2P fast-feedback workflow , which resolves the application’s targets at run time.
permissions:
contents: read
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 75
env:
XDG_CONFIG_HOME: ${{ runner.temp }}/corectl-ci
KUBECONFIG: ${{ runner.temp }}/kubeconfig
CORECTL_CONTEXT: ${{ vars.CORECTL_CONTEXT }}
CORECTL_PORTAL_URL: ${{ vars.CORECTL_PORTAL_URL }}
steps:
- name: Setup corectl
uses: coreeng/p2p/.github/actions/setup-corectl@v1
with:
version: ${{ vars.CORECTL_VERSION || 'latest' }}
# Obtain your deployment assets before deploying.
- name: Connect to cluster
run: |
portal_args=()
if [[ -n "$CORECTL_PORTAL_URL" ]]; then
portal_args+=(--url "$CORECTL_PORTAL_URL")
fi
corectl connect gcp-pre-prod --oidc github \
--context "$CORECTL_CONTEXT" "${portal_args[@]}" \
--kubeconfig "$KUBECONFIG"
- name: Deploy
run: helm upgrade --install payments ./chart --namespace payments --wait --timeout 60m
- name: Disconnect
if: always()
run: corectl disconnect --kubeconfig "$KUBECONFIG"Use separate configuration and kubeconfig files for concurrent jobs, including
matrix jobs on self-hosted runners. Do not cache these files across jobs.
disconnect --kubeconfig stops the connection selected by the file’s current
context, which is the Pinniped connection in the example. The registry session
has its own lease and stops forwarding after the CI job can no longer renew it.
A stopped or expired tunnel fails closed. It never falls back to direct cluster
access. The connect --timeout covers setup only; it does not limit the
subsequent deployment to two minutes.
OIDC assertions are renewed in memory before expiry. Each CI tunnel has its own renewable credential-capped five-minute maximum lease; the kubeconfig exec helper obtains fresh Pinniped credentials through the Kubernetes tunnel. This supports hour-long commands while the GitHub job can request assertions and Portal/Pinniped remain available. On transient renewal failure, existing streams retain their last verified lease. Explicit denial or expiry closes access; no human login or stale-credential fallback is attempted.
Operator configuration
Before a runner can connect, upgrade the cluster’s Control Agent and managed add-ons
to the release that supports CI access. The Control Agent configures a single GitHub
JWTAuthenticator for its cluster, reads and verifies the private Pinniped proxy’s
serving CA, and reports that connection to Portal. The tenant-provisioner chart,
rendered by the application’s native Argo CD Application, binds the repository
identity to the parent namespace’s admin and viewer roles in
the application namespace. HNC propagates those rights to subnamespaces created
by P2P; P2P still creates and manages those subnamespaces. The repository has no
team-namespace or cluster-wide rights from this grant.
Portal opens a CI tunnel only while an application with that repository is active, assigned to the requested managed cluster, and recently observed ready at its current revision. The Control Agent must also have reported a recently verified Pinniped connection for the cluster’s current registration generation. A creation operation successfully paused after repository configuration can qualify once the application is active, assigned and Ready; an incomplete or pending application cannot. These checks use the immutable numeric GitHub owner and repository IDs captured during application creation. Portal does not distinguish deployment branches, events or workflows; protect those with GitHub environments and required reviews when needed.
A context administrator uses the following Portal API endpoints with their normal human access token. CI tokens cannot use these endpoints:
| Method and path | Purpose |
|---|---|
DELETE /api/admin/ci/repositories/OWNER_ID/REPOSITORY_ID | Explicitly deny that repository, remove its generated Kubernetes grant on reconciliation, and invalidate active CI tunnel sessions |
PUT /api/admin/ci/repositories/OWNER_ID/REPOSITORY_ID | Clear an explicit deny; the repository still needs a ready application on the target cluster |
Names alone are not trust identities. Renames retain access; a transfer to a
different owner requires updating the application’s repository association. Older
catalogue entries without verified owner IDs cannot grant CI access. The Control
Agent reports connection metadata using its cluster credential; no manual cluster
connection registration is needed. Reports are tied to the current registration
generation, fixed github-actions authenticator and cluster-specific audience.
Portal accepts GitHub assertions only on /api/ci/tunnels/**, using the audience
urn:core-platform:ci:INSTANCE_UUID. corectl obtains this UUID through instance
discovery. It requests a separate assertion with Pinniped’s audience for certificate
issuance. No Keycloak workload client or GitHub subject-template customization is
needed. Human Keycloak authentication is unchanged.
Tunnel sessions are bound to the instance, context, cluster registration, GitHub repository, workflow run/attempt and a per-session client key. Renewal and revocation require a signature from that key. The receiving connector also verifies possession before forwarding and rechecks authorization during active connections. GitHub assertions and Pinniped private credentials remain in memory; protected local files hold the tunnel’s private state and proxy capability.
Pinniped supplies the Kubernetes identity and Kubernetes enforces its namespace
permissions. corectl does not send Impersonate-User headers, select a service
account, or grant a role. If service-account impersonation is configured, it must be
an explicit server-side mapping to a suitably restricted account. The tunnel does
not provide registry or workload-to-cloud credentials. GitLab and GitHub Enterprise
Server assertion sources are not yet implemented.