SECRETS_SETUP.md•5.74 kB
# Google Cloud Secret Manager Setup
This guide explains how to set up secrets in Google Cloud Secret Manager for the MCP Timezone Server deployment.
## Overview
The application uses a **hybrid approach** for configuration:
- **Non-sensitive values** are set directly in `cloudbuild.yaml` as environment variables
- **Sensitive values** are stored in Google Secret Manager and referenced by the Cloud Run service
## Required Secrets
Before deploying to Cloud Run, you must create the following secrets in Google Secret Manager:
| Secret Name | Description | Example Value |
|-------------|-------------|---------------|
| `jwt-secret` | Secret key for signing JWT tokens | A long random string (min 32 chars) |
| `oauth2-client-id` | OAuth2 provider client ID | `123456789-abcdef.apps.googleusercontent.com` |
| `oauth2-client-secret` | OAuth2 provider client secret | `GOCSPX-abc123def456...` |
| `allowed-emails` | Comma-separated list of allowed emails | `user1@example.com,user2@example.com` |
## Setup Instructions
### Prerequisites
1. Install Google Cloud SDK (`gcloud`)
2. Authenticate: `gcloud auth login`
3. Set your project: `gcloud config set project YOUR_PROJECT_ID`
4. **Enable Secret Manager API**:
```bash
gcloud services enable secretmanager.googleapis.com
```
Wait 1-2 minutes after enabling for the API to become available.
### Create Secrets
Run these commands to create all required secrets:
```bash
# 1. JWT Secret (generate a random 64-character string)
echo -n "$(openssl rand -hex 32)" | gcloud secrets create jwt-secret \
--data-file=- \
--replication-policy="automatic"
# 2. OAuth2 Client ID
echo -n "YOUR_OAUTH2_CLIENT_ID" | gcloud secrets create oauth2-client-id \
--data-file=- \
--replication-policy="automatic"
# 3. OAuth2 Client Secret
echo -n "YOUR_OAUTH2_CLIENT_SECRET" | gcloud secrets create oauth2-client-secret \
--data-file=- \
--replication-policy="automatic"
# 4. Allowed Emails
echo -n "user1@example.com,user2@example.com" | gcloud secrets create allowed-emails \
--data-file=- \
--replication-policy="automatic"
```
### Grant Cloud Run Access to Secrets
Cloud Run needs permission to read these secrets:
```bash
# Get your project number
PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)")
# Grant Secret Accessor role to the Cloud Run service account
gcloud secrets add-iam-policy-binding jwt-secret \
--member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
gcloud secrets add-iam-policy-binding oauth2-client-id \
--member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
gcloud secrets add-iam-policy-binding oauth2-client-secret \
--member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
gcloud secrets add-iam-policy-binding allowed-emails \
--member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
### Verify Secrets
List all secrets:
```bash
gcloud secrets list
```
View a secret's metadata (not the value):
```bash
gcloud secrets describe jwt-secret
```
Access a secret value (for verification):
```bash
gcloud secrets versions access latest --secret="jwt-secret"
```
## Updating Secrets
To update a secret with a new value:
```bash
echo -n "NEW_VALUE" | gcloud secrets versions add SECRET_NAME --data-file=-
```
Example:
```bash
echo -n "newuser@example.com,anotheruser@example.com" | gcloud secrets versions add allowed-emails --data-file=-
```
After updating a secret, redeploy your Cloud Run service for changes to take effect:
```bash
pnpm deploy
```
## Environment Variables vs Secrets
### Set in cloudbuild.yaml (Non-Sensitive)
- `MCP_TRANSPORT=http`
- `JWT_EXPIRES_IN=3600`
- `OAUTH2_AUTHORIZATION_URL`
- `OAUTH2_TOKEN_URL`
- `OAUTH2_USER_INFO_URL`
- `OAUTH2_SCOPE`
- `OAUTH2_CALLBACK_URL`
### Stored in Secret Manager (Sensitive)
- `JWT_SECRET` → secret: `jwt-secret`
- `OAUTH2_CLIENT_ID` → secret: `oauth2-client-id`
- `OAUTH2_CLIENT_SECRET` → secret: `oauth2-client-secret`
- `ALLOWED_EMAILS` → secret: `allowed-emails`
## Troubleshooting
### Error: "Secret not found"
Ensure you've created the secret and granted access to the Cloud Run service account.
### Error: "Permission denied"
Make sure the Cloud Run service account has the `secretmanager.secretAccessor` role for each secret.
### Secret not updating in Cloud Run
After updating a secret version, you must redeploy the Cloud Run service. The service doesn't automatically pick up new secret versions.
### Check Cloud Run environment
View the current environment configuration:
```bash
gcloud run services describe mcp-timezone-server \
--region=europe-west2 \
--format="value(spec.template.spec.containers[0].env)"
```
## Security Best Practices
1. **Never commit secrets to source control** - Always use Secret Manager for sensitive values
2. **Use least privilege** - Only grant `secretAccessor` role, not broader permissions
3. **Rotate secrets regularly** - Update OAuth2 credentials and JWT secrets periodically
4. **Audit access** - Review who has access to secrets in the GCP Console
5. **Use version pinning** - In production, consider pinning to specific secret versions instead of `:latest`
## References
- [Google Cloud Secret Manager Documentation](https://cloud.google.com/secret-manager/docs)
- [Cloud Run Secrets](https://cloud.google.com/run/docs/configuring/secrets)
- [IAM Permissions for Secrets](https://cloud.google.com/secret-manager/docs/access-control)