Skip to main content

Firebase Wiki Deployment Setup

📋 Related Issue: Issue #238 - Enable Firebase deployment from AI SWE agent dev container

Overview​

This document describes how to enable Firebase wiki deployment from the AI SWE agent dev container using cross-project service account permissions with IAM conditions to restrict access to the wiki site only.

Solution Architecture​

Key Components​

  1. Service Account: ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com

    • Lives in the -test project
    • Already configured in dev container via GOOGLE_APPLICATION_CREDENTIALS
  2. Target Project: construction-code-expert-dev

    • Hosts the Firebase project
    • Where wiki deployment happens
  3. Wiki Site: construction-code-expert-dev-wiki

    • Specific Firebase hosting site for the wiki
    • Only target the service account can deploy to

Security Features​

✅ Cross-Project Permissions: Service account from -test can deploy to -dev

✅ Hosting-Only Access: Role limited to Firebase Hosting (not functions, Firestore, etc.)

✅ Target Enforcement: Deployment script enforces --only hosting:wiki flag

✅ Application-Level Security: Firebase CLI respects target specification

âš ī¸ Note: Firebase roles don't support IAM conditions at project level (GCP limitation)

Setup Instructions​

Step 1: Grant IAM Permissions​

Run the setup script to grant permissions:

./cli/sdlc/setup-firebase-wiki-permissions.sh

This script will:

  • Grant roles/firebase.hostingAdmin role
  • Configure cross-project permissions
  • Enable Firebase Hosting deployment only

Manual Command (if you prefer):

gcloud projects add-iam-policy-binding construction-code-expert-dev \
--member="serviceAccount:ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com" \
--role="roles/firebase.hostingAdmin"

Note: IAM conditions are not supported for Firebase roles. Security is enforced by:

  1. Role is limited to hosting only (not functions, Firestore, etc.)
  2. Deployment script specifies --only hosting:wiki
  3. Firebase CLI enforces the target specification

Step 2: Verify Permissions​

./cli/sdlc/verify-firebase-wiki-permissions.sh

Expected output:

✅ IAM binding exists: roles/firebase.hostingAdmin
â„šī¸ Firebase roles don't support IAM conditions at project level
✅ Credentials file exists
✅ Credentials match expected service account

Step 3: Test Deployment​

cd wiki
firebase deploy --project=construction-code-expert-dev --only hosting:wiki

Or use the smart deployment script:

./cli/sdlc/wiki/deploy-to-firebase-smart.sh

How It Works​

Cross-Project IAM​

Service accounts can be granted permissions across projects:

┌─────────────────────────────┐
│ construction-code-expert- │
│ test │
│ │
│ ┌─────────────────────────┐ │
│ │ Service Account │ │
│ │ ai-swe-agent@... │ │
│ └─────────────────────────┘ │
└──────────────â”Ŧ──────────────┘
│
│ IAM Permission
│ with condition
│
â–ŧ
┌─────────────────────────────┐
│ construction-code-expert- │
│ dev │
│ │
│ ┌─────────────────────────┐ │
│ │ Firebase Hosting │ │
│ │ (role: hostingAdmin) │ │
│ │ │ │
│ │ Can deploy to all sites │ │
│ │ Target enforced by CLI │ │
│ └─────────────────────────┘ │
└─────────────────────────────┘

Security Enforcement​

Firebase roles don't support IAM conditions at the project level. Instead, security is enforced through:

1. Role Limitation

  • roles/firebase.hostingAdmin is limited to Firebase Hosting only
  • Cannot modify Firebase Functions, Firestore rules, or other resources

2. Target Specification

  • Deployment script always uses --only hosting:wiki
  • Firebase CLI enforces this target specification

3. Application-Level Control

  • Firebase CLI requires explicit target in deployment command
  • No way to accidentally deploy to wrong target without changing the script

Deployment Flow​

# 1. Dev container has credentials mounted
GOOGLE_APPLICATION_CREDENTIALS=/workspaces/construction-code-expert/.secrets/agent-credentials/construction-code-expert-test.ai-swe-agent.json

# 2. Deployment script detects credentials
./cli/sdlc/wiki/deploy-to-firebase-smart.sh

# 3. Firebase CLI uses service account
firebase deploy --project=construction-code-expert-dev --only hosting:wiki

# 4. IAM checks:
# ✅ Service account has firebase.hostingAdmin role
# ✅ Deployment proceeds

# 5. Target is enforced by script:
# ✅ Script always specifies --only hosting:wiki
# ✅ Cannot deploy to other targets without modifying the script

Verification​

Check IAM Binding​

gcloud projects get-iam-policy construction-code-expert-dev \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com" \
--format="table(bindings.role)"

Expected output:

ROLE
roles/firebase.hostingAdmin

Test Deployment​

# Should succeed - wiki site deployment using our script
cd wiki && ./cli/sdlc/wiki/deploy-to-firebase-smart.sh

# Manual deployment also works
cd wiki && firebase deploy --project=construction-code-expert-dev --only hosting:wiki

# Note: The service account CAN technically deploy to other targets if commanded
# Security relies on our deployment scripts only targeting wiki

Troubleshooting​

Deployment Fails with "Permission Denied"​

Problem: Error: HTTP Error: 403, Permission denied

Solutions:

  1. Check IAM binding exists:

    ./cli/sdlc/verify-firebase-wiki-permissions.sh
  2. Verify credentials are loaded:

    echo $GOOGLE_APPLICATION_CREDENTIALS
    cat $GOOGLE_APPLICATION_CREDENTIALS | jq .client_email
  3. Check you're deploying with correct project:

    # Verify project ID
    cat wiki/.firebaserc

    # Deploy explicitly
    firebase deploy --project=construction-code-expert-dev --only hosting:wiki

Wrong Service Account​

Problem: Deployment uses wrong service account

Solution: Ensure GOOGLE_APPLICATION_CREDENTIALS is set in dev container:

# Check environment variable
echo $GOOGLE_APPLICATION_CREDENTIALS

# Verify service account email
cat $GOOGLE_APPLICATION_CREDENTIALS | jq .client_email

Should show:

ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com

Role Not Sufficient​

Problem: Permission denied even with role granted

Solution: Verify the role is actually granted:

# Check IAM policy
gcloud projects get-iam-policy construction-code-expert-dev \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com"

# If missing, grant it
./cli/sdlc/setup-firebase-wiki-permissions.sh

Security Considerations​

Why Cross-Project Permissions Are Safe​

  1. Explicit Grant: Permissions must be explicitly granted (not automatic)
  2. Auditable: All cross-project access is logged in Cloud Audit Logs
  3. Revocable: Can be removed instantly if compromised
  4. Role-Limited: Only Firebase Hosting permissions, not full project access

Why Role Limitation Matters​

The firebase.hostingAdmin role is limited to hosting operations only:

What it CAN do:

  • ✅ Deploy to Firebase Hosting sites
  • ✅ Delete hosting releases
  • ✅ View hosting configuration

What it CANNOT do:

  • ❌ Update Firebase Functions
  • ❌ Modify Firestore security rules
  • ❌ Change Firebase Authentication settings
  • ❌ Access other Firebase resources

Application-Level Protection:

  • Our deployment scripts always specify --only hosting:wiki
  • Firebase CLI requires explicit target specification
  • Accidental deployment to other sites requires script modification (visible in version control)

Monitoring​

View deployment activity:

# View audit logs for Firebase deployments
gcloud logging read \
"resource.type=firebase.hosting.site
AND protoPayload.authenticationInfo.principalEmail=ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com" \
--project=construction-code-expert-dev \
--limit=10 \
--format=json

Rollback​

To remove permissions:

gcloud projects remove-iam-policy-binding construction-code-expert-dev \
--member="serviceAccount:ai-swe-agent@construction-code-expert-test.iam.gserviceaccount.com" \
--role="roles/firebase.hostingAdmin"

References​