Short definition
“Integrations” covers three kinds of external connections: GitHub repository authorization (as a deployment source), Providers (infrastructure/DNS/notification and other capability providers), and Plugins (extending Appaloft’s own behavior). All three are managed through a unified Connection model for authorization and revocation.
Why this concept exists
Deployment sources, DNS auto-configuration, notification delivery, and custom extension points are all fundamentally the same thing: “Appaloft uses an external system’s capability on your behalf.” Putting them under one Connection/Connector model means authorization, revocation, auditing, and security boundaries only need to be implemented once.
GitHub repositories
A GitHub repository ties a deployment to a traceable piece of source code: the repository, ref, working directory, and deployment identity need to be recorded together so retries, rollbacks, and previews can all come back to the same set of inputs.
# Check the current workspace's GitHub App installation status
appaloft github status
# Browse authorized repositories
appaloft github repositories --search webConfiguring a GitHub source requires confirming at least: the repository (owner/repo), the ref (branch/tag/commit SHA — production should use a stable branch, previews should use a pull request’s commit SHA), the directory (in a monorepo, don’t assume the repository root is the app directory), and the trigger method (manual / push-triggered / pull-request preview).
A pull request preview should use the commit SHA, not a moving branch name, so the preview page, logs, and later cleanup all correspond to the same commit.
Providers
A Provider handles infrastructure, DNS, and other external capabilities. Public docs only explain what you can configure and observe — they never expose internal Provider SDK types.
appaloft providers listEach Provider returns safe diagnostics: stable capability flags, enabled state, and a configured / not configured / partial configuration status. Diagnostics exist purely for visibility — they never include cloud SDK objects, raw responses, access tokens, or private keys.
Plugins
A Plugin extends Appaloft’s own capabilities and must explicitly declare compatibility, permissions, and sandbox assumptions.
appaloft plugins listAn incompatible plugin stays “visible but not activatable,” so you can tell “this extension point exists but is temporarily unavailable” apart from “this plugin doesn’t exist at all.” Plugin diagnostics never expose implementation internals, Provider SDK objects, or secret references.
Integrators that need to compose Appaloft with extra runtime behavior should import the public server factory instead of an internal source path:
import { createAppaloftServer } from "@appaloft/server";
const server = await createAppaloftServer({
extensions: [
{
name: "health-extension",
http: {
routes: [{ method: "GET", path: "/extension/health", handle: () => new Response("ok") }],
},
},
],
});Connection and Connector
A Connection is an authorization relationship Appaloft saves on your behalf (for example, a GitHub App installation, a DNS Provider authorization, or a Slack webhook). A ConnectorDefinition is a concrete connectable catalog entry (for example github-source or cloudflare-dns) — what you install, authorize, revoke, and audit is always a concrete Connector, never an abstract category.
appaloft connectors catalog
appaloft connectors list
appaloft connectors connect <connector>
appaloft connectors revoke <connectionId>
appaloft connectors plan --connector <connector> --capability <key> --parameters-json '<json>'
appaloft connectors accept --connector <connector> --capability <key> --plan-id <planId> --risk <risk> --summary <summary> --effects-json '<json>'
appaloft connectors apply --connector <connector> --capability <key> --parameters-json '<json>' --accepted-plan-id <acceptedPlanId>
# Capability-scoped shortcuts (still the same underlying Connection model)
appaloft dns plan <domain> --hostname <host> --target <target> --connector cloudflare-dnsDNS-type connections require passing three layers of validation before automatic configuration is possible: public DNS discovery (no authorization needed — it just infers a likely host provider from the domain), Connector authorization (proves you can access a particular Provider account), and Zone ownership matching (the authorized account must actually own a Zone covering that domain). Only once all three layers pass will Appaloft generate and apply a DNS change plan; failing any layer fails closed and points you to manual configuration.
Managed Kubernetes and multi-cluster capacity reuse the same Connector protocol. A concrete Connector can declare infrastructure.cluster.provision, import, inspect, readiness, state-eligibility, drain, delete, place, failover, recover, cleanup-orphans, handoff-traffic, failback-traffic, and traffic-status capabilities. The public contracts return only the target pool, deterministic placement reasons, placement epoch, fencing token, safe state/recovery/route/endpoint/health evidence, cost/support level, and residual-resource counts. Provider credentials, billing, quota, tenant policy, and commercial topology remain owned by the Cloud/Enterprise implementation that composes the Connector.
Provisioning, deletion, and failover mutate external infrastructure. Run connectors plan first, inspect cost, support, and cleanup evidence, accept that exact plan, and pass the returned acceptedPlanId to connectors apply. Parameters that drift from the accepted plan fail before provider effects. Insufficient capacity or an exhausted failover bound also fails explicitly instead of silently selecting a different topology.
Managed capacity-cell lifecycle
A managed capacity cell is one independently identified managed-cluster target in a target pool. A cell records whether Appaloft provisioned it or imported an existing cluster, whether it is accepting, draining, drained, deleted, or failed, its safe failure-domain identities, available capacity, active placement count, cost/support level, and what happens to the Provider resource when Appaloft management is deleted.
provision and import create the managed view, while inspect returns the same safe snapshot without plan acceptance. Run drain before delete: drain immediately sets available capacity to zero so new placements cannot enter, remains draining while active placements exist, and becomes drained only when that count reaches zero. Delete fails unless the cell is drained with zero active placements. Deleting an imported cell unregisters it from Appaloft but always retains the external cluster; a provisioned cell can request Provider deletion only through an explicitly accepted plan and a Provider adapter that is allowed to mutate.
The Web Console exposes these actions under Account settings → Connections. Import asks for the existing cluster reference plus its provider-neutral name/class and required capabilities. Drain and delete bind only to the exact cluster reference. Plan/readback shows origin, lifecycle, Provider-resource disposition, capacity, active placements, failure domains, cost/support, and residual Appaloft-owned resources; it never returns credentials, private bindings, or raw Provider objects.
Independent replacement readiness
infrastructure.cluster.readiness is a read-only connectors plan capability. Against an exact current target, placement epoch, workload policy, and target-pool snapshot, it returns a typed ready or blocked result. The result includes eligible candidates, independent failure domains, total available capacity, estimated cost, support level, and stable reason codes. A missing current target, shared or missing failure domain, zero capacity, non-ready status, missing capability, or policy exclusion is diagnosable blocked data rather than a transport error.
This check requires no plan acceptance and has no connectors apply path. It does not reserve capacity, increment the placement epoch, mint a fencing token, or mutate a cluster, workload, Provider, route, or DNS record. The result only describes the immutable snapshot at check time; a real traffic handoff must recheck fresh state, establish fencing, and accept an exact handoff plan.
Stateful failover eligibility and RPO/RTO evidence
infrastructure.cluster.state-eligibility is a read-only connectors plan capability. Every workload explicitly declares stateless, external-durable, restorable, or local-pvc; omitted state is never interpreted as stateless. The typed eligible or blocked result binds the exact workload, current target, replacement target, and evaluation time, and returns stable reason codes.
Stateless workloads can pass directly. External durable state supplies time-bounded independent-durability evidence. Restorable state supplies safe references to both an existing Storage Volume backup and a completed restore rehearsal, with different source and recovery targets. Both stateful profiles declare maximum recovery-point age (the RPO objective) and maximum recovery time (the RTO objective), while evidence records observed values. Missing or expired evidence, same-target recovery, or an observation above either objective returns blocked.
local-pvc always returns state_local_pvc_not_portable. Eligibility has no apply path and performs no backup, restore, fencing, Provider, or route effect. Failover/recover and Cloud-hosted traffic handoff bind a fresh eligible decision for the same workload/current/replacement tuple. Existing Storage Volume operations remain the only backup/restore lifecycle truth; eligibility does not copy that state.
Fenced traffic handoff and explicit failback
infrastructure.cluster.handoff-traffic binds an exact current route authority, safe endpoint references, fresh health evidence, current and next placement epochs, a rotated fencing token, and a rollback endpoint into one high-risk plan. After acceptance, the Connector re-reads both live route authority and replacement health before any effect. Drift in route, target, epoch, token, endpoint, or health validity fails closed.
Execution is ordered: read route, read health, fence the previous actor, move the route, verify the new authority, and clean bounded transient resources. A pre-move failure preserves the previous route. A post-move verification failure gets exactly one rollback attempt and returns rolled-back only after rollback verification. If rollback cannot be proven, the outcome is manual-intervention; uncertain authority is never reported as success. infrastructure.cluster.traffic-status is plan/readback only. infrastructure.cluster.failback-traffic is a freshly planned and accepted later epoch with a new fencing token, never a reverse replay of an old receipt.
Public responses contain only route, endpoint, health-proof reference, execution steps, outcome, rollback count, and residual-owned-resource evidence. Credentials, Provider bindings, account/zone identifiers, and raw Provider responses stay outside the public contract. Real DNS, load-balancer, or CDN writes still depend on whether the concrete Connector is authorized to apply them.
When the Cloud composition provides a managed-cluster Connector, the Web Console discovers these capabilities from Account settings → Connections. Mutating capabilities expose plan → accept → apply, while readiness, state-eligibility, and traffic-status expose plan/readback only. The Web form submits only safe cluster/workload/state-evidence/route/endpoint references, health evidence, required capabilities, and placement intent; Provider credentials, private bindings, and raw Provider objects never enter the form. Changing any plan-bound input immediately invalidates the prior acceptance, and apply stays disabled until the new exact plan is accepted. Plan and readback surfaces show only safe cost, support, selected region/target, placement epoch, state eligibility/RPO/RTO/reasons, traffic outcome/rollback, replacement capacity, and residual-owned-resource fields.
Common mistakes
- Treating a GitHub login as repository access authorization: login only represents identity — browsing repositories, receiving webhooks, or writing back deployment status all require completing GitHub integration authorization separately.
- Assuming Provider/Plugin diagnostics leak secrets: diagnostics are designed to only ever contain safe capability and status flags.
- Treating “DNS” as an installable thing:
dnsis a capability category — what’s actually installed and revoked is a concrete Connector (likecloudflare-dns).