Skip to content

Zero Trust Plugin

The @stacksolo/plugin-zero-trust provides Zero Trust network access using Google Cloud’s Identity-Aware Proxy (IAP). Secure your internal resources without VPNs - users authenticate with their Google identity.

For dynamic access control (grant/revoke access without redeploying), see the Zero Trust Auth Plugin.

Add to your stacksolo.config.json:

{
"project": {
"plugins": [
"@stacksolo/plugin-gcp-cdktf",
"@stacksolo/plugin-zero-trust"
],
"networks": [{
"name": "main",
"containers": [{ "name": "admin", "port": 3000 }],
"loadBalancer": {
"name": "gateway",
"domain": "app.yourcompany.com",
"enableHttps": true,
"redirectHttpToHttps": true,
"routes": [{ "path": "/admin/*", "backend": "admin" }]
}
}],
"zeroTrust": {
"iapWebBackends": [{
"name": "admin-protection",
"backend": "admin",
"allowedMembers": ["domain:yourcompany.com"],
"supportEmail": "admin@yourcompany.com"
}]
}
}
}

After deployment:

  1. Get the load balancer IP from outputs
  2. Point your DNS to the load balancer IP
  3. Wait 15-60 minutes for SSL certificate provisioning
  4. Users visit https://app.yourcompany.com/admin → Google login appears automatically
ResourceConfig KeyPurpose
IAP Web BackendzeroTrust.iapWebBackendsProtect web apps with Google login
IAP TunnelzeroTrust.iapTunnelsSSH/TCP access to VMs without public IPs

Control who can access using allowedMembers:

FormatExampleScope
Individualuser:alice@example.comSingle person
Groupgroup:team@example.comGoogle Group members
Domaindomain:example.comAnyone with @example.com account
// Single person
"allowedMembers": ["user:alice@mycompany.com"]
// Team via Google Group
"allowedMembers": ["group:developers@mycompany.com"]
// Entire company
"allowedMembers": ["domain:mycompany.com"]
// Mix (internal + external contractor)
"allowedMembers": [
"domain:mycompany.com",
"user:contractor@gmail.com"
]

Protect web applications with Google login. No code changes needed.

PropertyTypeRequiredDescription
namestringYesConfiguration name
backendstringYesBackend name to protect (must match a function, container, or ui)
allowedMembersstring[]YesWho can access
supportEmailstringYesEmail for OAuth consent screen
applicationTitlestringNoTitle shown on login screen
{
"zeroTrust": {
"iapWebBackends": [{
"name": "admin-protection",
"backend": "admin",
"allowedMembers": ["domain:mycompany.com"],
"supportEmail": "admin@mycompany.com",
"applicationTitle": "Admin Dashboard"
}]
}
}

After deployment: Users visit the URL → Google login prompt → access granted (if in allowedMembers).


Secure SSH/TCP access to VMs without exposing public IPs.

PropertyTypeRequiredDescription
namestringYesConfiguration name
targetInstancestringYesVM instance name
targetZonestringYesZone (e.g., us-central1-a)
allowedMembersstring[]YesWho can access
allowedPortsnumber[]NoPorts to allow (default: [22])
networkstringNoVPC network name (default: default)
{
"zeroTrust": {
"iapTunnels": [{
"name": "dev-ssh",
"targetInstance": "my-vm",
"targetZone": "us-central1-a",
"allowedMembers": ["group:developers@mycompany.com"],
"allowedPorts": [22, 3306]
}]
}
}

After deployment, users access via:

Terminal window
# SSH
gcloud compute ssh my-vm --zone=us-central1-a --tunnel-through-iap
# Database tunnel
gcloud compute start-iap-tunnel my-vm 3306 \
--zone=us-central1-a \
--local-host-port=localhost:3306

Public API + protected admin panel + SSH access to dev VM.

{
"project": {
"name": "my-saas",
"gcpProjectId": "my-gcp-project",
"region": "us-central1",
"plugins": [
"@stacksolo/plugin-gcp-cdktf",
"@stacksolo/plugin-zero-trust"
],
"networks": [{
"name": "main",
"functions": [
{ "name": "api", "allowUnauthenticated": true }
],
"containers": [
{ "name": "admin", "port": 3000 }
],
"uis": [
{ "name": "docs", "framework": "vue" }
],
"loadBalancer": {
"name": "gateway",
"domain": "my-saas.example.com",
"enableHttps": true,
"redirectHttpToHttps": true,
"routes": [
{ "path": "/api/*", "backend": "api" },
{ "path": "/admin/*", "backend": "admin" },
{ "path": "/*", "backend": "docs" }
]
}
}],
"zeroTrust": {
"iapWebBackends": [{
"name": "admin-protection",
"backend": "admin",
"allowedMembers": [
"domain:mycompany.com",
"user:contractor@gmail.com"
],
"supportEmail": "admin@mycompany.com",
"applicationTitle": "Admin Dashboard"
}],
"iapTunnels": [
{
"name": "dev-ssh",
"targetInstance": "dev-vm",
"targetZone": "us-central1-a",
"allowedMembers": ["group:engineering@mycompany.com"],
"allowedPorts": [22]
},
{
"name": "db-access",
"targetInstance": "prod-db",
"targetZone": "us-central1-a",
"allowedMembers": ["group:dba@mycompany.com"],
"allowedPorts": [5432]
}
]
}
}
}
ResourceAccess
/api/*Public (anyone)
/admin/*IAP protected (mycompany.com + contractor)
/* (docs)Public (anyone)
dev-vm SSHIAP tunnel (engineering group)
prod-db PostgreSQLIAP tunnel (dba group)
Terminal window
# Public API - just works
curl https://my-saas.example.com/api/health
# Admin panel - visit in browser, Google login required
open https://my-saas.example.com/admin
# SSH to dev VM
gcloud compute ssh dev-vm --zone=us-central1-a --tunnel-through-iap
# Connect to prod database
gcloud compute start-iap-tunnel prod-db 5432 \
--zone=us-central1-a \
--local-host-port=localhost:5432
psql -h localhost -p 5432 -U postgres

No StackSolo CLI needed. After you deploy, users access with:

ResourceHow Users Access
Web appsVisit URL in browser (Google login prompt)
SSHgcloud compute ssh INSTANCE --tunnel-through-iap
TCP tunnelgcloud compute start-iap-tunnel INSTANCE PORT
ResourceMonthly Cost
IAP TunnelFree
IAP Web BackendFree

Standard charges apply for underlying resources (VMs, Load Balancers).

  1. Google Cloud CLI installed and authenticated
  2. Terraform installed
  3. A custom domain for HTTPS (IAP requires HTTPS)
  4. Ability to manage DNS records for your domain

Note: OAuth consent screen and client are automatically created - no manual GCP Console setup needed.

IAP requires HTTPS, which means you need:

  1. A custom domain - Configure domain in your load balancer config
  2. DNS access - You’ll need to create an A record pointing to the load balancer IP
  3. SSL certificate - StackSolo uses Google-managed certificates (auto-provisioned)
{
"loadBalancer": {
"name": "gateway",
"domain": "app.yourcompany.com",
"enableHttps": true,
"redirectHttpToHttps": true,
"routes": [...]
}
}
PropertyRequired for IAPDescription
domainYesYour custom domain
enableHttpsYesMust be true for IAP
redirectHttpToHttpsRecommendedRedirect HTTP to HTTPS
  1. Get the load balancer IP from Terraform outputs:

    Terminal window
    cd .stacksolo/cdktf && terraform output
    # Look for: gateway_LoadBalancerIp = "34.102.x.x"
  2. Configure DNS - Create an A record:

    app.yourcompany.com → 34.102.x.x
  3. Wait for SSL - Google-managed certificates take 15-60 minutes to provision. You can check status in the GCP Console under “Certificate Manager”

  4. Access your app - Visit https://app.yourcompany.com/admin - Google login will appear