Customer deployment · Google Cloud
Deploy Fort on
Google Cloud.
Fill in your Terraform variables, apply, then open Fort’s operator console and sign in.
Fort runs inside your cloud. The template provisions a VM in a new dedicated VPC and subnet, an encrypted retained disk, a stable external IP and a service account scoped to the bootstrap secret. The existing console is served by Fort over HTTPS on port 7451. The API and internal services stay private.
Early access. Ask your Fort contact for the current qualified binaries and template checkout. Release packaging is still being completed; there is no assumed public release or download command.
Before you apply. The template has offline validation. A fresh VM, your network, certificates and company sign-in still need qualification in your environment.
Before Terraform
Prepare your cloud, hostname
and credentials.
You need Terraform 1.9 or later, below 2.0; cloud credentials authorized to create the resources; an IPv4 source range that can reach the VM; a DNS hostname; a trusted TLS certificate and key; and OIDC clients for company sign-in.
Choose a billing-enabled project, region and zone. Select an exact ubuntu-2404-noble-amd64-vDATE image in ubuntu-os-cloud, rather than a moving image family. Supply an existing Secret Manager secret name in that project and an exact numbered version.
The template creates a dedicated VPC so broad rules in the default network cannot widen its access. It enables Compute, IAM and Secret Manager without disabling those APIs on removal. An optional existing public Cloud DNS managed zone gets the hostname’s A record.
The default subnet is 10.80.0.0/24. Avoid overlap with Docker and backend networks. Connecting private backends in another VPC needs your approved peering and routing. Review inherited organization firewall policies separately.
SSH is off by default. If you enable restricted SSH for maintenance, operators also need OS Login and permission to act as the VM’s service account. The template creates no human IAM grants. IAP access additionally requires its IAM role and SSH source range.
Choose the build
Supply direct HTTPS URLs and separate SHA-256 hashes for fort and fortd from the same qualified Linux x86_64 build. The daemon must include the production console assets. The bootstrap verifies both downloads before execution. Get the hashes from your trusted build process; do not use latest, redirecting links or credentials in URLs.
Prepare the bootstrap secret
Use your cloud’s protected secret input or existing secret-management process. The secret is a JSON object with required tls_certificate (the full PEM chain) and tls_private_key (unencrypted PEM). Optional keys are console_oidc_client_secret and step_up_client_secret; omit unused keys.
The certificate must match your hostname, remain valid for at least a day, and chain to a CA your team’s browsers trust. Terraform takes only the secret reference and exact version. Keep private keys and client-secret values out of tfvars, Terraform data sources, VM metadata, command arguments and shell history.
Existing Fort sign-in
Register Fort with your
identity provider.
Choose the hostname first. For fort.company.com, register this exact redirect URI for the browser client:
https://fort.company.com:7451/auth/callbackThe issuer must support OIDC discovery and device authorization for CLI sign-in and approval step-up. The console uses authorization code with PKCE. A console session alone cannot finish an approval.
- Choose the clients.If one public client supports both grants, use it as
oidc_client_id. If your issuer needs separate clients, set the device client there and the web client asconsole_oidc_client_id. Required secrets belong in the bootstrap secret. - Choose the first administrator.Set
admin_groupto a group emitted in the configuredoidc_groups_claim. Alternatively, setadmin_subjectto one immutable OIDCsuband omit the group. An email address is not an OIDC subject. - Check issuer and scope.The installer names the issuer
default. It binds only the selected group or subject globally to Fort’s admin role and verifies the binding before completing setup.
Google sign-in needs a Web application client for the console and a separate TVs and Limited Input devices client for device flow. Put their required secrets in the corresponding bootstrap-secret fields. Creating clients and assigning users remain customer IdP administration.
Reviewable configuration
Fill in one configuration file.
Use the deploy/terraform/customer/gcp folder from your Fort checkout, with its sibling shared folder intact. Copy terraform.tfvars.example to terraform.tfvars and replace every placeholder. Each environment needs its own state and resource name.
name = "fort"
project_id = "your-billing-enabled-project"
region = "us-central1"
zone = "us-central1-a"
image_name = "ubuntu-2404-noble-amd64-vREPLACE" # exact image in ubuntu-os-cloud
console_cidrs = ["203.0.113.4/32"] # replace with your public egress IP or reachable network
bootstrap_secret_id = "fort-bootstrap" # existing secret in this project
bootstrap_secret_version = "1" # exact numbered version, not latest
# dns_zone_name = "company-public" # existing public Cloud DNS zone; else add A record yourself
# subnet_cidr = "10.80.0.0/24" # new dedicated network; avoid Docker/backend overlaps
# SSH is off by default. OS Login permissions are needed in addition to this CIDR:
# ssh_cidrs = ["203.0.113.4/32"]
# Supply binaries from the SAME qualified Linux x86_64 build, with console assets embedded.
# Use direct HTTPS URLs, not redirecting GitHub links, signed URLs or latest.
fort = {
hostname = "fort.company.com"
environment_name = "Production"
fort_url = "https://builds.company.com/fort/BUILD/fort"
fort_sha256 = "REPLACE_WITH_64_LOWERCASE_HEX_CHARACTERS"
fortd_url = "https://builds.company.com/fort/BUILD/fortd"
fortd_sha256 = "REPLACE_WITH_64_LOWERCASE_HEX_CHARACTERS"
oidc_issuer = "https://idp.company.com/REALM"
oidc_client_id = "fort-device"
oidc_groups_claim = "groups"
# oidc_audience = "..." # only if your issuer's expected ID-token audience differs
# Set only if the browser uses a different client. Its secret, if required, goes
# in the existing bootstrap secret, never in this file. Step-up uses the device client.
console_oidc_client_id = "fort-web"
# step_up_client_id = "..." # defaults to oidc_client_id
admin_group = "fort-admins" # must be emitted by the issuer in oidc_groups_claim
# Alternatively remove admin_group and set admin_subject = "immutable OIDC sub"
}
console_cidrs contains the IPv4 addresses that actually reach Fort, usually your corporate egress ranges. An empty list and a whole-internet CIDR are refused. If you omit the DNS-zone input, add the hostname’s A record yourself using the returned public_ip; do not add an AAAA record.
The defaults are 4 vCPU, 16 GiB and a 120 GiB disk. Review current regional VM, disk, IP, DNS and secret-access pricing. Use your organization’s encrypted, access-controlled Terraform state backend. This single-VM installation does not provide high availability.
Infrastructure, then readiness
Apply and open the console.
terraform init
terraform plan -out=install.tfplan
terraform apply install.tfplan
terraform output console_url
terraform output oidc_callback_urlRead the plan before applying it. Terraform finishing means the infrastructure exists; the guest installation can still be running or have failed. Look in Compute Engine serial-port output for Fort bootstrap ready: https://....
The bootstrap uses the existing fort up installer, fetches TLS and client secrets by reference, and confirms the admin binding. Completion requires healthy Fort/OpenShell services, fort doctor and real console assets. It never prints the temporary bootstrap token.
sudo test -f /var/lib/fort-onboarding/done
sudo fort doctor
sudo systemctl is-active fortd openshell-gateway- Open the returned HTTPS URL.Use an allowed network and check the certificate without a browser exception. The URL includes
:7451. - Sign in with company SSO.Confirm the selected administrator can access Agents and Access. An unassigned account must not gain admin.
- Verify the boundaries.Check that API/internal ports are closed externally, disallowed sources cannot reach the console or SSH, and approval decisions still require a separate human step-up.
Adding model-provider keys remains a CLI operation; the console does not accept secret values. Continue with agent and tool-server setup ↗ after installation is verified.
After the console is ready
Deploy the agent
and its tools.
The template installs Fort and its console. Next, prepare an agent image and the tool-server images it will call. Backend operations and their credentials belong in tool servers outside the agent sandbox.
Fort runs declared tool servers in separate Docker containers on the same Fort VM. Declare their images, backend secrets, health checks and tool policy, then configure the agent’s MCP client to use Fort’s injected tool URL. fort apply deploys and maintains the containers.
Finish onboarding with a healthy tool server and one successful, allowed read-only call from the agent to the backend. A running VM or sandbox alone does not prove this path works.
Set up the agent and tool server ↗After installation
Keep evidence safe
through maintenance.
Retry an unchanged failed bootstrap with sudo python3 /var/lib/fort-onboarding/bootstrap.py through an approved root administration path. The error identifies its stage without exposing upstream command or secret payloads. A completed unchanged install is a no-op; changed configuration is refused.
If the temporary bootstrap token expired before the administrator was bound, inspect the installation and reissue into root’s credential store with sudo env -u SUDO_UID -u SUDO_GID -u SUDO_USER HOME=/root /usr/local/bin/fort up --reissue-bootstrap-token before retrying. Clearing the sudo caller variables is essential: setting HOME alone still delivers the new token to the SSH operator, while the Python bootstrap reads root’s credentials. Do not reissue credentials for unrelated failures.
For TLS renewal or client-secret rotation, use a maintenance window and your approved root-only secret retrieval process. Atomically replace the relevant files under /etc/fort/customer, preserving fort ownership, certificate mode 0644 and key/client-secret mode 0600. For device-secret rotation, explicitly reinstall the installed copy with sudo fort up --step-up-client-secret-file /etc/fort/customer/device.secret; plain fort up preserves its old copy. For certificate or console-client secret changes, run sudo fort up with its recorded settings. Explicitly run sudo systemctl restart fortd to load the new TLS and browser-client secret, then sudo fort doctor, service checks and browser sign-in/step-up checks. Restarting Fort ends browser sessions, and governed calls fail closed during the restart. Rotation is explicit maintenance; changing tfvars does not replay the original bootstrap.
The VM has Terraform prevent_destroy and Compute Engine deletion protection. Its encrypted root disk is retained if the VM is deliberately deleted. Before replacement, create and verify a Fort backup, copy it off-host and test restore. A retained disk is not a backup.
Intentional replacement or deletion requires a reviewed change removing Terraform’s protection and disabling the cloud protection. Record the retained disk identity, then delete that disk separately only after confirming your evidence-retention policy and off-host backups. Stopped VMs still incur disk/IP charges. Do not suspend a running Fort VM.
Keep the full deploy/terraform/customer/README.md from the same template checkout as your operating reference.