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.
Quick Start
Section titled “Quick Start”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:
- Get the load balancer IP from outputs
- Point your DNS to the load balancer IP
- Wait 15-60 minutes for SSL certificate provisioning
- Users visit
https://app.yourcompany.com/admin→ Google login appears automatically
Resources
Section titled “Resources”| Resource | Config Key | Purpose |
|---|---|---|
| IAP Web Backend | zeroTrust.iapWebBackends | Protect web apps with Google login |
| IAP Tunnel | zeroTrust.iapTunnels | SSH/TCP access to VMs without public IPs |
Access Control
Section titled “Access Control”Control who can access using allowedMembers:
| Format | Example | Scope |
|---|---|---|
| Individual | user:alice@example.com | Single person |
| Group | group:team@example.com | Google Group members |
| Domain | domain:example.com | Anyone with @example.com account |
Examples
Section titled “Examples”// 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"]IAP Web Backend
Section titled “IAP Web Backend”Protect web applications with Google login. No code changes needed.
Configuration
Section titled “Configuration”| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Configuration name |
backend | string | Yes | Backend name to protect (must match a function, container, or ui) |
allowedMembers | string[] | Yes | Who can access |
supportEmail | string | Yes | Email for OAuth consent screen |
applicationTitle | string | No | Title shown on login screen |
Example
Section titled “Example”{ "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).
IAP Tunnel
Section titled “IAP Tunnel”Secure SSH/TCP access to VMs without exposing public IPs.
Configuration
Section titled “Configuration”| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Configuration name |
targetInstance | string | Yes | VM instance name |
targetZone | string | Yes | Zone (e.g., us-central1-a) |
allowedMembers | string[] | Yes | Who can access |
allowedPorts | number[] | No | Ports to allow (default: [22]) |
network | string | No | VPC network name (default: default) |
Example
Section titled “Example”{ "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:
# SSHgcloud compute ssh my-vm --zone=us-central1-a --tunnel-through-iap
# Database tunnelgcloud compute start-iap-tunnel my-vm 3306 \ --zone=us-central1-a \ --local-host-port=localhost:3306Full Example
Section titled “Full Example”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] } ] } }}What This Creates
Section titled “What This Creates”| Resource | Access |
|---|---|
/api/* | Public (anyone) |
/admin/* | IAP protected (mycompany.com + contractor) |
/* (docs) | Public (anyone) |
dev-vm SSH | IAP tunnel (engineering group) |
prod-db PostgreSQL | IAP tunnel (dba group) |
After Deployment
Section titled “After Deployment”# Public API - just workscurl https://my-saas.example.com/api/health
# Admin panel - visit in browser, Google login requiredopen https://my-saas.example.com/admin
# SSH to dev VMgcloud compute ssh dev-vm --zone=us-central1-a --tunnel-through-iap
# Connect to prod databasegcloud compute start-iap-tunnel prod-db 5432 \ --zone=us-central1-a \ --local-host-port=localhost:5432psql -h localhost -p 5432 -U postgresUser Access
Section titled “User Access”No StackSolo CLI needed. After you deploy, users access with:
| Resource | How Users Access |
|---|---|
| Web apps | Visit URL in browser (Google login prompt) |
| SSH | gcloud compute ssh INSTANCE --tunnel-through-iap |
| TCP tunnel | gcloud compute start-iap-tunnel INSTANCE PORT |
| Resource | Monthly Cost |
|---|---|
| IAP Tunnel | Free |
| IAP Web Backend | Free |
Standard charges apply for underlying resources (VMs, Load Balancers).
Prerequisites
Section titled “Prerequisites”- Google Cloud CLI installed and authenticated
- Terraform installed
- A custom domain for HTTPS (IAP requires HTTPS)
- Ability to manage DNS records for your domain
Note: OAuth consent screen and client are automatically created - no manual GCP Console setup needed.
HTTPS and DNS Setup
Section titled “HTTPS and DNS Setup”IAP requires HTTPS, which means you need:
- A custom domain - Configure
domainin your load balancer config - DNS access - You’ll need to create an A record pointing to the load balancer IP
- SSL certificate - StackSolo uses Google-managed certificates (auto-provisioned)
Load Balancer Configuration
Section titled “Load Balancer Configuration”{ "loadBalancer": { "name": "gateway", "domain": "app.yourcompany.com", "enableHttps": true, "redirectHttpToHttps": true, "routes": [...] }}| Property | Required for IAP | Description |
|---|---|---|
domain | Yes | Your custom domain |
enableHttps | Yes | Must be true for IAP |
redirectHttpToHttps | Recommended | Redirect HTTP to HTTPS |
After Deployment
Section titled “After Deployment”-
Get the load balancer IP from Terraform outputs:
Terminal window cd .stacksolo/cdktf && terraform output# Look for: gateway_LoadBalancerIp = "34.102.x.x" -
Configure DNS - Create an A record:
app.yourcompany.com → 34.102.x.x -
Wait for SSL - Google-managed certificates take 15-60 minutes to provision. You can check status in the GCP Console under “Certificate Manager”
-
Access your app - Visit
https://app.yourcompany.com/admin- Google login will appear
Learn More
Section titled “Learn More”- Config Schema Reference - Full configuration options
- Source code