OSVauco/docs/SECRETS-SETUP.md
Chris Christiansen 9fcb9c354a
Some checks are pending
Check Python Version Consistency / Check Python Version (push) Waiting to run
feat(core): Fresh initialization - Deploy v3.6.1 Singularity Architecture
2026-09-03 04:03:09 +00:00

132 lines
5.1 KiB
Markdown

# Google Cloud Secret Manager Setup Guide
This guide provides the `gcloud` commands to set up secrets in Google Cloud Secret Manager and configure the Cloud Run service to use them.
## 1. Create Secrets in Secret Manager
First, create the `CHAT_WEBHOOK_URL` and `GOOGLE_API_KEY` secrets.
```bash
# Create CHAT_WEBHOOK_URL secret
echo -n "your-chat-webhook-url" | gcloud secrets create CHAT_WEBHOOK_URL --data-file=-
# Create GOOGLE_API_KEY secret
echo -n "your-google-api-key" | gcloud secrets create GOOGLE_API_KEY --data-file=-
```
Replace `"your-chat-webhook-url"` and `"your-google-api-key"` with your actual secret values.
## 2. Grant Secret Accessor Role
Grant the `Secret Manager Secret Accessor` role to the service account that your Cloud Run service uses. By default, this is the default compute service account.
```bash
# Get your project number
PROJECT_NUMBER=$(gcloud projects describe <YOUR_PROJECT_ID> --format="value(projectNumber)")
# Construct the service account email
SERVICE_ACCOUNT_EMAIL="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
# Grant access to CHAT_WEBHOOK_URL
gcloud secrets add-iam-policy-binding CHAT_WEBHOOK_URL
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}"
--role="roles/secretmanager.secretAccessor"
# Grant access to GOOGLE_API_KEY
gcloud secrets add-iam-policy-binding GOOGLE_API_KEY
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}"
--role="roles/secretmanager.secretAccessor"
```
Replace `<YOUR_PROJECT_ID>` with your Google Cloud project ID.
## 3. Update `bridge/server.py` to Use Secrets
Modify `bridge/server.py` to read secrets from Secret Manager when it's not running in a local development environment.
Here is the code patch to apply to `bridge/server.py`. This patch adds a function to retrieve secrets and modifies the `post_to_chat` function to use it.
```python
# Add this import at the top of bridge/server.py
from google.cloud import secretmanager
# Add this function to bridge/server.py
def get_secret(secret_id: str, project_id: str, version_id: str = "latest") -> str:
"""
Get a secret from Google Cloud Secret Manager.
"""
try:
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(name=name)
return response.payload.data.decode("UTF-8")
except Exception as e:
print(f"Error accessing secret {secret_id}: {e}")
return None
# The following is a patch for the lifespan context manager in bridge/server.py
# --- old
# from dotenv import load_dotenv
# load_dotenv()
# --- new
from dotenv import load_dotenv
from google.cloud import secretmanager
load_dotenv()
def get_secret(secret_id: str, project_id: str, version_id: str = "latest") -> str:
"""
Get a secret from Google Cloud Secret Manager.
"""
try:
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(name=name)
return response.payload.data.decode("UTF-8")
except Exception as e:
print(f"Error accessing secret {secret_id}: {e}")
return None
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
if os.getenv("GAE_ENV", "").startswith("standard"):
project_id = os.getenv("GOOGLE_CLOUD_PROJECT")
if project_id:
os.environ["CHAT_WEBHOOK_URL"] = get_secret("CHAT_WEBHOOK_URL", project_id)
os.environ["GOOGLE_API_KEY"] = get_secret("GOOGLE_API_KEY", project_id)
if not os.path.exists(STATE_DIR):
os.makedirs(STATE_DIR)
watcher_task = asyncio.create_task(state_watcher_with_approval_check())
print("Bridge server started, watcher with approval check is running.")
yield
# Shutdown
watcher_task.cancel()
try:
await watcher_task
except asyncio.CancelledError:
print("Watcher task cancelled.")
```
Apply this patch to your `bridge/server.py` file. This code checks for the `GAE_ENV` environment variable, which is set in App Engine and Cloud Run environments. If it's present, it fetches the secrets from Secret Manager and sets them as environment variables for the application to use.
---
## GitHub Actions Secrets (aktive per 2026-05-25)
Disse secrets er satt i [OSVauco → Settings → Secrets → Actions](https://github.com/vauco-saas/OSVauco/settings/secrets/actions)
og brukes av `.github/workflows/backup-gdrive-nightly.yml`.
| Secret | Formål | Status |
|---|---|---|
| `RCLONE_GDRIVE_SA_JSON` | Hele JSON-nøkkelen for `vauco-gdrive-backup` service account | ✅ Aktiv |
| `GDRIVE_BACKUP_FOLDER_ID` | GDrive-mappe-ID (`0AB6RSjTedmwEUk9PVA`) for backup-destinasjon | ✅ Aktiv |
**Service account:** `vauco-gdrive-backup@propane-will-491900-m5.iam.gserviceaccount.com`
**Forny nøkkel ved behov:**
```bash
gcloud iam service-accounts keys create ~/vauco-gdrive-backup-sa-new.json \
--iam-account=vauco-gdrive-backup@propane-will-491900-m5.iam.gserviceaccount.com
# Oppdater GitHub Secret RCLONE_GDRIVE_SA_JSON med nytt innhold
```