Skip to content

Commit 35b4285

Browse files
authored
Merge pull request #3520 from PolicyEngine/fix/runtime-adc-secret-manager
Use runtime ADC for gateway auth secret access
2 parents 0134827 + 939b716 commit 35b4285

7 files changed

Lines changed: 68 additions & 26 deletions

File tree

.github/workflows/pr.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ jobs:
5252
test_env_vars:
5353
name: Test environment variables
5454
runs-on: ubuntu-latest
55+
permissions:
56+
contents: read
57+
id-token: write
5558
steps:
5659
- name: Checkout repo
5760
uses: actions/checkout@v4
@@ -62,7 +65,8 @@ jobs:
6265
- name: Auth
6366
uses: google-github-actions/auth@v2
6467
with:
65-
credentials_json: ${{ secrets.GCP_SA_KEY }}
68+
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
69+
service_account: ${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}
6670
- name: Wait until policyengine_us version is available on PyPI
6771
run: .github/wait-for-pypi.sh
6872
- name: Install dependencies
@@ -77,6 +81,9 @@ jobs:
7781
name: Test
7882
runs-on: ubuntu-latest
7983
needs: test_env_vars
84+
permissions:
85+
contents: read
86+
id-token: write
8087
steps:
8188
- name: Checkout repo
8289
uses: actions/checkout@v4
@@ -91,7 +98,8 @@ jobs:
9198
- name: Auth
9299
uses: google-github-actions/auth@v2
93100
with:
94-
credentials_json: ${{ secrets.GCP_SA_KEY }}
101+
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
102+
service_account: ${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}
95103
- name: Set up Cloud SDK
96104
uses: google-github-actions/setup-gcloud@v2
97105
with:

.github/workflows/push.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ jobs:
115115
(github.repository == 'PolicyEngine/policyengine-api')
116116
&& (github.event.head_commit.message == 'Update PolicyEngine API')
117117
environment: staging
118+
permissions:
119+
contents: read
120+
id-token: write
118121
outputs:
119122
version: ${{ steps.version.outputs.version }}
120123
url: ${{ steps.version_url.outputs.url }}
@@ -132,7 +135,8 @@ jobs:
132135
- name: GCP authentication
133136
uses: "google-github-actions/auth@v2"
134137
with:
135-
credentials_json: "${{ secrets.GCP_SA_KEY }}"
138+
workload_identity_provider: "${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}"
139+
service_account: "${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}"
136140
- name: Set up GCloud
137141
uses: "google-github-actions/setup-gcloud@v2"
138142
- name: Validate App Engine deployment configuration
@@ -149,7 +153,6 @@ jobs:
149153
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
150154
APP_ENGINE_PROMOTE: "0"
151155
POLICYENGINE_DB_PASSWORD: ${{ secrets.POLICYENGINE_DB_PASSWORD }}
152-
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GCP_SA_KEY }}
153156
POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN: ${{ secrets.POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN }}
154157
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
155158
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -225,6 +228,9 @@ jobs:
225228
(github.repository == 'PolicyEngine/policyengine-api')
226229
&& (github.event.head_commit.message == 'Update PolicyEngine API')
227230
environment: production
231+
permissions:
232+
contents: read
233+
id-token: write
228234
steps:
229235
- name: Checkout repo
230236
uses: actions/checkout@v4
@@ -239,7 +245,8 @@ jobs:
239245
- name: GCP authentication
240246
uses: "google-github-actions/auth@v2"
241247
with:
242-
credentials_json: "${{ secrets.GCP_SA_KEY }}"
248+
workload_identity_provider: "${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}"
249+
service_account: "${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}"
243250
- name: Set up GCloud
244251
uses: "google-github-actions/setup-gcloud@v2"
245252
- name: Validate App Engine deployment configuration
@@ -256,7 +263,6 @@ jobs:
256263
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
257264
APP_ENGINE_PROMOTE: "0"
258265
POLICYENGINE_DB_PASSWORD: ${{ secrets.POLICYENGINE_DB_PASSWORD }}
259-
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GCP_SA_KEY }}
260266
POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN: ${{ secrets.POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN }}
261267
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
262268
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ deploy:
2323
gcloud config set app/cloud_build_timeout 2400
2424
cp gcp/policyengine_api/* .
2525
y | gcloud app deploy --service-account=github-deployment@policyengine-api.iam.gserviceaccount.com
26-
rm app.yaml
27-
rm Dockerfile
28-
rm .gac.json
29-
rm .dbpw
26+
rm -f app.yaml
27+
rm -f Dockerfile
28+
rm -f .dbpw
3029

3130
changelog:
3231
python .github/bump_version.py
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Stop baking Google application credentials into the App Engine runtime image so Secret Manager access uses the attached runtime service account.

gcp/export.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
import os
2-
from pathlib import Path
32

4-
GAE = os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
5-
# If it's a filepath, read the file. Otherwise, it'll be JSON
6-
try:
7-
Path(GAE).resolve(strict=True)
8-
with open(GAE, "r") as f:
9-
GAE = f.read()
10-
except Exception:
11-
pass
123
DB_PD = os.environ["POLICYENGINE_DB_PASSWORD"]
134
GITHUB_MICRODATA_TOKEN = os.environ["POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN"]
145
ANTHROPIC_API_KEY = os.environ["ANTHROPIC_API_KEY"]
@@ -20,10 +11,7 @@
2011
GATEWAY_AUTH_CLIENT_ID = os.environ["GATEWAY_AUTH_CLIENT_ID"]
2112
GATEWAY_AUTH_CLIENT_SECRET_RESOURCE = os.environ["GATEWAY_AUTH_CLIENT_SECRET_RESOURCE"]
2213

23-
# Export GAE to to .gac.json and DB_PD to .dbpw in the current directory
24-
25-
with open(".gac.json", "w") as f:
26-
f.write(GAE)
14+
# Export DB_PD to .dbpw in the current directory
2715

2816
with open(".dbpw", "w") as f:
2917
f.write(DB_PD)

gcp/policyengine_api/Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ FROM python:3.11
22

33
RUN apt-get update && apt-get install -y build-essential redis-server && rm -rf /var/lib/apt/lists/*
44

5-
ENV GOOGLE_APPLICATION_CREDENTIALS .gac.json
65
ENV POLICYENGINE_DB_PASSWORD .dbpw
76
ENV POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN .github_microdata_token
87
ENV ANTHROPIC_API_KEY .anthropic_api_key

policyengine_api/gcp_logging.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1-
from google.cloud.logging import Client
1+
import logging
2+
from typing import Optional
23

3-
logger = Client().logger("policyengine-api")
4+
5+
class _LazyGoogleLogger:
6+
"""Lazily initialize Google Cloud Logging and fall back to stderr."""
7+
8+
def __init__(self, logger_name: str):
9+
self._logger_name = logger_name
10+
self._google_logger = None
11+
self._initialization_failed = False
12+
self._fallback_logger = logging.getLogger(logger_name)
13+
14+
def _get_google_logger(self):
15+
if self._google_logger is not None:
16+
return self._google_logger
17+
if self._initialization_failed:
18+
return None
19+
try:
20+
from google.cloud.logging import Client
21+
22+
self._google_logger = Client().logger(self._logger_name)
23+
return self._google_logger
24+
except Exception:
25+
self._initialization_failed = True
26+
return None
27+
28+
def log_struct(
29+
self,
30+
info: dict,
31+
severity: str = "INFO",
32+
*,
33+
labels: Optional[dict] = None,
34+
) -> None:
35+
google_logger = self._get_google_logger()
36+
if google_logger is not None:
37+
google_logger.log_struct(info, severity=severity, labels=labels)
38+
return
39+
40+
level = getattr(logging, severity.upper(), logging.INFO)
41+
self._fallback_logger.log(level, "%s", info)
42+
43+
44+
logger = _LazyGoogleLogger("policyengine-api")

0 commit comments

Comments
 (0)