access/README.md
David Soria Parra 8eb21f43ff
feat: provision GWS accounts for implicit maintainers (SDK teams, WGs)
GWS user accounts were only created for members whose direct roles had
google.provisionUser (lead/core maintainers, moderators, maintainers,
registry-wg). SDK maintainers and working-group members who opted in by
adding firstName/lastName/googleEmailPrefix (e.g. #148, #150, #152)
silently got no account.

- Move provisionUser from GoogleConfig to the Role level, and add it to
  the implicit-maintainer containers (sdk-maintainers, working-groups)
  plus the standalone maintainer roles (docs, inspector, mcpb,
  reference-servers, use-mcp, server-identity-wg, wg/ig facilitators).
- Eligibility now walks github.parent chains (hasProvisionUserRole),
  matching GitHub team-nesting semantics, so e.g. python-sdk members
  qualify via sdk-maintainers.
- validate-config now errors when a googleEmailPrefix would be a silent
  no-op (no eligible role and not an existing GWS user), so opt-in PRs
  like #150 fail CI instead of quietly doing nothing.

Newly provisioned on next apply: marcelo@, alexhancock@, liad@.
ochafik is now eligible but already has an account (existingGWSUser).
2026-07-27 10:17:46 +01:00

5.1 KiB

MCP Access Management

Infrastructure as Code for managing access to MCP community resources using Pulumi.

What This Manages

  • GitHub Teams: Automatically syncs team memberships in the MCP GitHub organization
  • Google Workspace Groups: Automatically syncs group memberships for @modelcontextprotocol.io email accounts
    • Email Groups: Groups with isEmailGroup: true accept emails from anyone (including external users) and notify all members. External posts are moderated for security.
  • Google Workspace User Accounts: Provisions @modelcontextprotocol.io accounts for members of roles with provisionUser: true (directly, or via a role nested under one through github.parent — e.g. SDK teams under sdk-maintainers, working groups under working-groups)

Opting in to a Google Workspace account (maintainers)

If you're a maintainer — explicitly or implicitly (SDK maintainers, working group members, etc.) — and want an @modelcontextprotocol.io account, open a PR adding the following fields to your entry in src/config/users.ts:

{
  github: 'your-github-username',
  // ...
  firstName: 'Your',
  lastName: 'Name',
  googleEmailPrefix: 'yourname', // -> yourname@modelcontextprotocol.io
  memberOf: [ROLE_IDS.MAINTAINERS /* , ... */],
},

Once merged, Pulumi provisions the account. An admin will share your initial password (retrievable via pulumi stack output --show-secrets newGWSUserPasswords).

Deployment

Production Deployment (Automated)

Note: Production deployment is automatically handled by GitHub Actions. All merges to the main branch trigger an automatic deployment via the configured GitHub Actions workflow.

Manual Deployment

Pre-requisites:

  1. Authenticate with GCP: gcloud auth application-default login
  2. Get the passphrase file passphrase.prod.txt from the maintainers
  3. Preview changes: make preview
  4. Deploy changes: make up

Key Management

Required GitHub Secrets (for CI/CD)

The following secrets must be configured in GitHub Actions for automated deployments:

  • GCP_PROD_SERVICE_ACCOUNT_KEY: GCP service account key

    • Used to authenticate with Google Cloud Storage for Pulumi state (gs://mcp-access-prod-pulumi-state)
    • Should be a JSON key file for a service account with Storage Admin permissions
    • See "Setting Up GCS Backend" below for setup instructions
  • PULUMI_PROD_PASSPHRASE: Passphrase for encrypting Pulumi state

    • Used to decrypt encrypted values in Pulumi stack configuration
    • Keep this secure - if lost, you cannot decrypt your Pulumi state

Initial Setup

If setting up this infrastructure for the first time:

1. Set Up Service Account

# Create project and enable APIs
gcloud projects create mcp-access-prod
gcloud config set project mcp-access-prod
gcloud services enable storage.googleapis.com
gcloud services enable admin.googleapis.com
gcloud services enable groupssettings.googleapis.com

# Create service account
gcloud iam service-accounts create pulumi-svc \
  --display-name="MCP Access Management Service Account" \
  --description="Service account for Pulumi state and Google Workspace management"

# Grant storage admin permissions (for Pulumi state)
gcloud projects add-iam-policy-binding mcp-access-prod \
  --member="serviceAccount:pulumi-svc@mcp-access-prod.iam.gserviceaccount.com" \
  --role="roles/storage.admin"

# Create key
gcloud iam service-accounts keys create sa-key.json \
  --iam-account=pulumi-svc@mcp-access-prod.iam.gserviceaccount.com

# Create GCS bucket for Pulumi state
gsutil mb gs://mcp-access-prod-pulumi-state

Then:

  1. In Google Workspace Admin Console, go to Account → Admin roles
  2. Select Groups Admin role (or create a custom role with these privileges):
    • Read, create, update, and delete groups
    • Read and update group members
  3. Click Assign service accounts
  4. Add your service account email: pulumi-svc@mcp-access-prod.iam.gserviceaccount.com

2. Initialize Pulumi Stack

# Login to Pulumi backend (GCS)
pulumi login gs://mcp-access-prod-pulumi-state

# Create production stack
export PULUMI_CONFIG_PASSPHRASE_FILE=passphrase.prod.txt
pulumi stack init prod

# Configure application secrets in Pulumi
pulumi config set --secret googleworkspace:credentials "$(cat sa-key.json)"
pulumi config set --secret github:token "ghp_your_github_token_here"

3. Configure GitHub Actions Secrets

Add the CI/CD secrets to GitHub Actions (repository settings → Secrets and variables → Actions):

  • GCP_PROD_SERVICE_ACCOUNT_KEY: Content of sa-key.json
  • PULUMI_PROD_PASSPHRASE: The passphrase you set above