Skip to content

Conversation

@bokelley
Copy link
Contributor

Summary

Implements automatic service account provisioning for Google Ad Manager integration. Instead of partners sending us their service account credentials, we now create service accounts in our GCP project and provide partners with just the email address to add to their GAM.

Partner Workflow:

  1. Partner requests service account integration in Admin UI
  2. We create service account in our GCP project → provide email
  3. Partner adds email to their GAM with appropriate permissions
  4. Partner tests connection

Security Model:
Two-factor control ensures both parties maintain control:

  • Private Key (we control): Stored encrypted, used to authenticate API calls
  • GAM User List (partner controls): Partner must add email to their GAM

Both are required for access. Partner can revoke anytime by removing the email from GAM.

Implementation Details

Backend:

  • New GCPServiceAccountService class for managing service account lifecycle
  • Uses Google Cloud IAM API to create service accounts programmatically
  • Stores encrypted service account keys in database (Fernet encryption)
  • Two new API endpoints: /create-service-account and /get-service-account-email
  • Database migration adds gam_service_account_email field to track provisioned accounts

Frontend:

  • New UI section in tenant settings for service account integration
  • Create button, email display with copy-to-clipboard, setup instructions
  • Test connection button for verification

Configuration:

  • GCP_PROJECT_ID environment variable (set to "bok-playground" in fly.toml)
  • Management service account with IAM permissions (serviceAccountAdmin, serviceAccountKeyAdmin)
  • Credentials provided via GOOGLE_APPLICATION_CREDENTIALS_JSON Fly secret

Security:

  • Proper cleanup of temporary credentials files (destructor + explicit cleanup method)
  • Encrypted storage of service account keys
  • Two-factor control model documented

Testing

  • Created actual service account in bok-playground: adcp-manager@bok-playground.iam.gserviceaccount.com
  • Granted IAM permissions for creating/managing service accounts
  • UI tested with create flow and connection testing

Documentation

  • Updated docs/gam-service-account-setup.md with security model explanation
  • Created docs/gcp-service-account-provisioning-setup.md with deployment guide
  • Updated .env.example with GCP configuration

Files Changed

  • pyproject.toml: Added google-cloud-iam>=2.19.1 dependency
  • alembic/versions/661c474053fa_*.py: Migration for service account email field
  • src/core/database/models.py: Added gam_service_account_email field with documentation
  • src/services/gcp_service_account_service.py: New service class (350+ lines)
  • src/admin/blueprints/gam.py: Two new API endpoints
  • templates/tenant_settings.html: Service account integration UI section
  • static/js/tenant_settings.js: JavaScript handlers for SA creation
  • fly.toml: Added GCP_PROJECT_ID environment variable
  • .env.example: Documented GCP configuration
  • .gitignore: Added service account key patterns
  • docs/*.md: Updated documentation

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Instead of partners sending service account credentials, we now create
service accounts in our GCP project and provide partners with just the
email address to add to their GAM.

Partner workflow:
1. Request service account in Admin UI
2. We create SA in our GCP project → provide email
3. Partner adds email to their GAM with appropriate permissions
4. Partner tests connection

Security model:
- Two-factor control: private key (we control) + GAM user list (partner controls)
- Both required for access; partner can revoke anytime

Implementation:
- New GCPServiceAccountService class using Google Cloud IAM API
- Encrypted storage of service account keys (Fernet)
- Database migration adds gam_service_account_email field
- Two new API endpoints: /create-service-account, /get-service-account-email
- UI section with create button, email display, setup instructions
- Proper cleanup of temporary credentials files (security fix)

Configuration:
- GCP_PROJECT_ID environment variable (set in fly.toml)
- Management service account with IAM permissions
- Credentials via GOOGLE_APPLICATION_CREDENTIALS_JSON Fly secret

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley merged commit 936aec4 into main Oct 19, 2025
8 checks passed
EmmaLouise2018 pushed a commit that referenced this pull request Oct 24, 2025
)

Instead of partners sending service account credentials, we now create
service accounts in our GCP project and provide partners with just the
email address to add to their GAM.

Partner workflow:
1. Request service account in Admin UI
2. We create SA in our GCP project → provide email
3. Partner adds email to their GAM with appropriate permissions
4. Partner tests connection

Security model:
- Two-factor control: private key (we control) + GAM user list (partner controls)
- Both required for access; partner can revoke anytime

Implementation:
- New GCPServiceAccountService class using Google Cloud IAM API
- Encrypted storage of service account keys (Fernet)
- Database migration adds gam_service_account_email field
- Two new API endpoints: /create-service-account, /get-service-account-email
- UI section with create button, email display, setup instructions
- Proper cleanup of temporary credentials files (security fix)

Configuration:
- GCP_PROJECT_ID environment variable (set in fly.toml)
- Management service account with IAM permissions
- Credentials via GOOGLE_APPLICATION_CREDENTIALS_JSON Fly secret

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
danf-newton pushed a commit to Newton-Research-Inc/salesagent that referenced this pull request Nov 24, 2025
…dcontextprotocol#509)

Instead of partners sending service account credentials, we now create
service accounts in our GCP project and provide partners with just the
email address to add to their GAM.

Partner workflow:
1. Request service account in Admin UI
2. We create SA in our GCP project → provide email
3. Partner adds email to their GAM with appropriate permissions
4. Partner tests connection

Security model:
- Two-factor control: private key (we control) + GAM user list (partner controls)
- Both required for access; partner can revoke anytime

Implementation:
- New GCPServiceAccountService class using Google Cloud IAM API
- Encrypted storage of service account keys (Fernet)
- Database migration adds gam_service_account_email field
- Two new API endpoints: /create-service-account, /get-service-account-email
- UI section with create button, email display, setup instructions
- Proper cleanup of temporary credentials files (security fix)

Configuration:
- GCP_PROJECT_ID environment variable (set in fly.toml)
- Management service account with IAM permissions
- Credentials via GOOGLE_APPLICATION_CREDENTIALS_JSON Fly secret

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants