refactor: migrate Secrets Manager secrets to SSM Parameter Store (free tier)

This commit is contained in:
daniel
2026-05-13 12:55:16 -05:00
parent 3a34e61479
commit 74f74ef877
10 changed files with 81 additions and 81 deletions

View File

@@ -20,8 +20,8 @@
"OAUTH_START_URL": "https://sptejrymri.execute-api.us-east-1.amazonaws.com/oauth/start", "OAUTH_START_URL": "https://sptejrymri.execute-api.us-east-1.amazonaws.com/oauth/start",
"USERS_TABLE_NAME": "agent-claw-users", "USERS_TABLE_NAME": "agent-claw-users",
"WORKSPACE_BUCKET_NAME": "agent-claw-workspace-495395224548", "WORKSPACE_BUCKET_NAME": "agent-claw-workspace-495395224548",
"TELEGRAM_BOT_TOKEN_SECRET_ARN": "arn:aws:secretsmanager:us-east-1:495395224548:secret:agent-claw/telegram-bot-token-Oq3in3", "TELEGRAM_BOT_TOKEN_SSM_PARAM": "/agent-claw/telegram-bot-token",
"BRAVE_API_KEY_SECRET_ARN": "arn:aws:secretsmanager:us-east-1:495395224548:secret:agent-claw/brave-api-key-uUSgzi", "BRAVE_API_KEY_SSM_PARAM": "/agent-claw/brave-api-key",
"SCHEDULER_LAMBDA_ARN": "arn:aws:lambda:us-east-1:495395224548:function:agent-claw-scheduler" "SCHEDULER_LAMBDA_ARN": "arn:aws:lambda:us-east-1:495395224548:function:agent-claw-scheduler"
} }
} }

View File

@@ -19,14 +19,14 @@ class TelegramAdapter:
if self._token is None: if self._token is None:
with self._lock: with self._lock:
if self._token is None: if self._token is None:
secret_arn = self._secret_arn or os.environ.get( param_name = self._secret_arn or os.environ.get(
'TELEGRAM_BOT_TOKEN_SECRET_ARN', 'TELEGRAM_BOT_TOKEN_SSM_PARAM',
'arn:aws:secretsmanager:us-east-1:495395224548:secret:agent-claw/telegram-bot-token-Oq3in3' '/agent-claw/telegram-bot-token'
) )
sm = boto3.client('secretsmanager') ssm = boto3.client('ssm')
self._token = sm.get_secret_value( self._token = ssm.get_parameter(
SecretId=secret_arn Name=param_name, WithDecryption=True
)['SecretString'] )['Parameter']['Value']
return self._token return self._token
def _api(self, method: str, data: dict) -> dict: def _api(self, method: str, data: dict) -> dict:

View File

@@ -15,12 +15,12 @@ def _get_brave_key() -> str:
if _brave_key is None: if _brave_key is None:
with _brave_lock: with _brave_lock:
if _brave_key is None: if _brave_key is None:
secret_arn = os.environ.get( param_name = os.environ.get(
'BRAVE_API_KEY_SECRET_ARN', 'BRAVE_API_KEY_SSM_PARAM',
'arn:aws:secretsmanager:us-east-1:495395224548:secret:agent-claw/brave-api-key-uUSgzi' '/agent-claw/brave-api-key'
) )
sm = boto3.client('secretsmanager') ssm = boto3.client('ssm')
_brave_key = sm.get_secret_value(SecretId=secret_arn)['SecretString'] _brave_key = ssm.get_parameter(Name=param_name, WithDecryption=True)['Parameter']['Value']
return _brave_key return _brave_key

View File

@@ -8,6 +8,7 @@ import * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';
import * as apigatewayv2integrations from 'aws-cdk-lib/aws-apigatewayv2-integrations'; import * as apigatewayv2integrations from 'aws-cdk-lib/aws-apigatewayv2-integrations';
import * as iam from 'aws-cdk-lib/aws-iam'; import * as iam from 'aws-cdk-lib/aws-iam';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'; import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import * as events from 'aws-cdk-lib/aws-events'; import * as events from 'aws-cdk-lib/aws-events';
import * as eventsTargets from 'aws-cdk-lib/aws-events-targets'; import * as eventsTargets from 'aws-cdk-lib/aws-events-targets';
import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources'; import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
@@ -20,25 +21,33 @@ export class AgentClawStack extends cdk.Stack {
super(scope, id, props); super(scope, id, props);
// ── Context parameters ───────────────────────────────────────────────── // ── Context parameters ─────────────────────────────────────────────────
const telegramBotTokenSecretArn = this.node.tryGetContext('telegramBotTokenSecretArn') as string | undefined; const telegramBotTokenParamName = this.node.tryGetContext('telegramBotTokenParamName') as string | undefined;
const braveApiKeySecretArn = this.node.tryGetContext('braveApiKeySecretArn') as string | undefined; const braveApiKeyParamName = this.node.tryGetContext('braveApiKeyParamName') as string | undefined;
const googleOAuthClientParamName = this.node.tryGetContext('googleOAuthClientParamName') as string | undefined;
const existingWorkspaceBucketName = this.node.tryGetContext('workspaceBucketName') as string | undefined; const existingWorkspaceBucketName = this.node.tryGetContext('workspaceBucketName') as string | undefined;
const runtime1Arn = this.node.tryGetContext('runtime1Arn') as string | undefined; const runtime1Arn = this.node.tryGetContext('runtime1Arn') as string | undefined;
if (!telegramBotTokenSecretArn) { if (!telegramBotTokenParamName) {
throw new Error('Context param required: telegramBotTokenSecretArn'); throw new Error('Context param required: telegramBotTokenParamName');
} }
if (!braveApiKeySecretArn) { if (!braveApiKeyParamName) {
throw new Error('Context param required: braveApiKeySecretArn'); throw new Error('Context param required: braveApiKeyParamName');
}
if (!googleOAuthClientParamName) {
throw new Error('Context param required: googleOAuthClientParamName');
} }
// ── Secrets (reference existing) ─────────────────────────────────────── // ── SSM Parameters (reference existing SecureString params) ────────────
const botTokenSecret = secretsmanager.Secret.fromSecretCompleteArn( const ssmParamArns = [
this, 'TelegramBotToken', telegramBotTokenSecretArn `arn:aws:ssm:${this.region}:${this.account}:parameter${telegramBotTokenParamName}`,
); `arn:aws:ssm:${this.region}:${this.account}:parameter${braveApiKeyParamName}`,
const braveApiKeySecret = secretsmanager.Secret.fromSecretCompleteArn( `arn:aws:ssm:${this.region}:${this.account}:parameter${googleOAuthClientParamName}`,
this, 'BraveApiKey', braveApiKeySecretArn ];
);
const ssmReadPolicy = new iam.PolicyStatement({
actions: ['ssm:GetParameter'],
resources: ssmParamArns,
});
// ── S3 workspace bucket ──────────────────────────────────────────────── // ── S3 workspace bucket ────────────────────────────────────────────────
const workspaceBucket = existingWorkspaceBucketName const workspaceBucket = existingWorkspaceBucketName
@@ -94,13 +103,13 @@ export class AgentClawStack extends cdk.Stack {
memorySize: 128, memorySize: 128,
environment: { environment: {
MESSAGE_QUEUE_URL: messageQueue.queueUrl, MESSAGE_QUEUE_URL: messageQueue.queueUrl,
TELEGRAM_BOT_TOKEN_SECRET_ARN: telegramBotTokenSecretArn, TELEGRAM_BOT_TOKEN_SSM_PARAM: telegramBotTokenParamName,
TELEGRAM_WEBHOOK_SECRET: '', // set via SSM or direct env after deploy TELEGRAM_WEBHOOK_SECRET: '', // set via SSM or direct env after deploy
ATTACHMENTS_BUCKET_NAME: workspaceBucket.bucketName, ATTACHMENTS_BUCKET_NAME: workspaceBucket.bucketName,
}, },
}); });
messageQueue.grantSendMessages(tgIngestFn); messageQueue.grantSendMessages(tgIngestFn);
botTokenSecret.grantRead(tgIngestFn); tgIngestFn.addToRolePolicy(ssmReadPolicy);
workspaceBucket.grantWrite(tgIngestFn); workspaceBucket.grantWrite(tgIngestFn);
// ── Lambda: agent-runner ─────────────────────────────────────────────── // ── Lambda: agent-runner ───────────────────────────────────────────────
@@ -114,8 +123,8 @@ export class AgentClawStack extends cdk.Stack {
environment: { environment: {
SESSION_TABLE_NAME: sessionTable.tableName, SESSION_TABLE_NAME: sessionTable.tableName,
WORKSPACE_BUCKET_NAME: workspaceBucket.bucketName, WORKSPACE_BUCKET_NAME: workspaceBucket.bucketName,
TELEGRAM_BOT_TOKEN_SECRET_ARN: telegramBotTokenSecretArn, TELEGRAM_BOT_TOKEN_SSM_PARAM: telegramBotTokenParamName,
BRAVE_API_KEY_SECRET_ARN: braveApiKeySecretArn, BRAVE_API_KEY_SSM_PARAM: braveApiKeyParamName,
RUNTIME_1_ARN: runtime1Arn ?? 'PLACEHOLDER_SET_AFTER_RUNTIME_DEPLOY', RUNTIME_1_ARN: runtime1Arn ?? 'PLACEHOLDER_SET_AFTER_RUNTIME_DEPLOY',
AWS_REGION_NAME: 'us-east-1', AWS_REGION_NAME: 'us-east-1',
}, },
@@ -125,8 +134,7 @@ export class AgentClawStack extends cdk.Stack {
usersTable.grantReadWriteData(agentRunnerFn); usersTable.grantReadWriteData(agentRunnerFn);
agentRunnerFn.addEnvironment('USERS_TABLE_NAME', usersTable.tableName); agentRunnerFn.addEnvironment('USERS_TABLE_NAME', usersTable.tableName);
workspaceBucket.grantRead(agentRunnerFn); workspaceBucket.grantRead(agentRunnerFn);
botTokenSecret.grantRead(agentRunnerFn); agentRunnerFn.addToRolePolicy(ssmReadPolicy);
braveApiKeySecret.grantRead(agentRunnerFn);
messageQueue.grantConsumeMessages(agentRunnerFn); messageQueue.grantConsumeMessages(agentRunnerFn);
// AgentCore invoke permission // AgentCore invoke permission
@@ -172,8 +180,7 @@ export class AgentClawStack extends cdk.Stack {
resources: ['*'], resources: ['*'],
})); }));
workspaceBucket.grantRead(runtime1Role); workspaceBucket.grantRead(runtime1Role);
botTokenSecret.grantRead(runtime1Role); runtime1Role.addToPolicy(ssmReadPolicy);
braveApiKeySecret.grantRead(runtime1Role);
usersTable.grantReadWriteData(runtime1Role); usersTable.grantReadWriteData(runtime1Role);
// Google secret grants added after workspace_mcp section below // Google secret grants added after workspace_mcp section below
runtime1Role.addToPolicy(new iam.PolicyStatement({ runtime1Role.addToPolicy(new iam.PolicyStatement({
@@ -192,15 +199,12 @@ export class AgentClawStack extends cdk.Stack {
// and fed back as context param runtime1Arn. // and fed back as context param runtime1Arn.
// ── Google Workspace MCP ────────────────────────────────────────────── // ── Google Workspace MCP ──────────────────────────────────────────────
const googleOAuthClientSecret = secretsmanager.Secret.fromSecretCompleteArn(
this, 'GoogleOAuthClient', 'arn:aws:secretsmanager:us-east-1:495395224548:secret:agent-claw/google-oauth-client-subXHl'
);
// workspace-mcp Lambda execution role (import existing — created during initial setup) // workspace-mcp Lambda execution role (import existing — created during initial setup)
const _workspaceMcpRole = iam.Role.fromRoleName( const _workspaceMcpRole = iam.Role.fromRoleName(
this, 'WorkspaceMcpRole', 'agent-claw-workspace-mcp-role' this, 'WorkspaceMcpRole', 'agent-claw-workspace-mcp-role'
); );
googleOAuthClientSecret.grantRead(_workspaceMcpRole); _workspaceMcpRole.addToPrincipalPolicy?.(ssmReadPolicy);
// Grant workspace-mcp role read access to all per-user Google credential secrets // Grant workspace-mcp role read access to all per-user Google credential secrets
(_workspaceMcpRole as iam.Role).addToPrincipalPolicy?.(new iam.PolicyStatement({ (_workspaceMcpRole as iam.Role).addToPrincipalPolicy?.(new iam.PolicyStatement({
sid: 'PerUserGoogleCredentialsRead', sid: 'PerUserGoogleCredentialsRead',
@@ -225,8 +229,7 @@ export class AgentClawStack extends cdk.Stack {
conditions: { StringEquals: { 'lambda:FunctionUrlAuthType': 'AWS_IAM' } }, conditions: { StringEquals: { 'lambda:FunctionUrlAuthType': 'AWS_IAM' } },
})); }));
// Grant AgentCore execution role read access to Google OAuth client + per-user credentials // Grant AgentCore execution role read access to per-user Google credentials (stays in Secrets Manager)
googleOAuthClientSecret.grantRead(runtime1Role);
runtime1Role.addToPolicy(new iam.PolicyStatement({ runtime1Role.addToPolicy(new iam.PolicyStatement({
sid: 'PerUserGoogleCredentialsReadRuntime', sid: 'PerUserGoogleCredentialsReadRuntime',
actions: ['secretsmanager:GetSecretValue'], actions: ['secretsmanager:GetSecretValue'],
@@ -250,22 +253,15 @@ export class AgentClawStack extends cdk.Stack {
timeout: cdk.Duration.seconds(30), timeout: cdk.Duration.seconds(30),
memorySize: 128, memorySize: 128,
environment: { environment: {
GOOGLE_OAUTH_CLIENT_SECRET_ARN: googleOAuthClientSecret.secretArn, GOOGLE_OAUTH_CLIENT_SSM_PARAM: googleOAuthClientParamName,
USERS_TABLE_NAME: usersTable.tableName, USERS_TABLE_NAME: usersTable.tableName,
TELEGRAM_BOT_TOKEN_SECRET_ARN: telegramBotTokenSecretArn, TELEGRAM_BOT_TOKEN_SSM_PARAM: telegramBotTokenParamName,
// OAUTH_REDIRECT_URI set after API GW URL is known — injected via addEnvironment below // OAUTH_REDIRECT_URI set after API GW URL is known — injected via addEnvironment below
OAUTH_REDIRECT_URI: 'PLACEHOLDER', OAUTH_REDIRECT_URI: 'PLACEHOLDER',
}, },
}); });
googleOAuthClientSecret.grantRead(oauthHandlerFn); oauthHandlerFn.addToRolePolicy(ssmReadPolicy);
botTokenSecret.grantRead(oauthHandlerFn);
usersTable.grantReadWriteData(oauthHandlerFn); usersTable.grantReadWriteData(oauthHandlerFn);
// Explicit access to the OAuth client secret (fromSecretNameV2 wildcard may not resolve)
oauthHandlerFn.addToRolePolicy(new iam.PolicyStatement({
sid: 'GoogleOAuthClientSecretExact',
actions: ['secretsmanager:GetSecretValue'],
resources: ['arn:aws:secretsmanager:us-east-1:495395224548:secret:agent-claw/google-oauth-client-subXHl'],
}));
// Grant OAuth handler write access to per-user credential secrets // Grant OAuth handler write access to per-user credential secrets
oauthHandlerFn.addToRolePolicy(new iam.PolicyStatement({ oauthHandlerFn.addToRolePolicy(new iam.PolicyStatement({
sid: 'PerUserGoogleCredentialsWrite', sid: 'PerUserGoogleCredentialsWrite',
@@ -344,10 +340,10 @@ export class AgentClawStack extends cdk.Stack {
timeout: cdk.Duration.seconds(30), timeout: cdk.Duration.seconds(30),
memorySize: 128, memorySize: 128,
environment: { environment: {
TELEGRAM_BOT_TOKEN_SECRET_ARN: telegramBotTokenSecretArn, TELEGRAM_BOT_TOKEN_SSM_PARAM: telegramBotTokenParamName,
}, },
}); });
botTokenSecret.grantRead(schedulerFn); schedulerFn.addToRolePolicy(ssmReadPolicy);
// Allow EventBridge to invoke the scheduler Lambda // Allow EventBridge to invoke the scheduler Lambda
schedulerFn.addPermission('EventBridgeInvoke', { schedulerFn.addPermission('EventBridgeInvoke', {
principal: new iam.ServicePrincipal('events.amazonaws.com'), principal: new iam.ServicePrincipal('events.amazonaws.com'),

View File

@@ -163,11 +163,11 @@ def handler(event, context):
user_profile['status'] = 'active' user_profile['status'] = 'active'
prompt = f"[System: User just registered with name '{name}'. Welcome them warmly and ask how you can help.]" prompt = f"[System: User just registered with name '{name}'. Welcome them warmly and ask how you can help.]"
else: else:
bot_token_secret_arn = os.environ.get('TELEGRAM_BOT_TOKEN_SECRET_ARN', '') bot_token_secret_arn = os.environ.get('TELEGRAM_BOT_TOKEN_SSM_PARAM', '')
bot_token = '' bot_token = ''
if bot_token_secret_arn: if bot_token_secret_arn:
sm = boto3.client('secretsmanager', region_name='us-east-1') ssm = boto3.client('ssm', region_name='us-east-1')
bot_token = sm.get_secret_value(SecretId=bot_token_secret_arn)['SecretString'] bot_token = ssm.get_parameter(Name=bot_token_secret_arn, WithDecryption=True)['Parameter']['Value']
send_telegram_direct(chat_id, bot_token, "Hi! I don't recognize you yet. What's your name?", thread_id=message_thread_id) send_telegram_direct(chat_id, bot_token, "Hi! I don't recognize you yet. What's your name?", thread_id=message_thread_id)
return return
# ── Get or create AgentCore session ────────────────────────────────── # ── Get or create AgentCore session ──────────────────────────────────
@@ -212,7 +212,7 @@ def handler(event, context):
'type': channel, 'type': channel,
'target_id': str(chat_id), 'target_id': str(chat_id),
'message_thread_id': message_thread_id, 'message_thread_id': message_thread_id,
'bot_token_secret_arn': os.environ.get('TELEGRAM_BOT_TOKEN_SECRET_ARN', ''), 'bot_token_secret_arn': os.environ.get('TELEGRAM_BOT_TOKEN_SSM_PARAM', ''),
}, },
} }
@@ -232,11 +232,11 @@ def handler(event, context):
# Process streaming response: buffer text chunks and send to Telegram as paragraphs arrive # Process streaming response: buffer text chunks and send to Telegram as paragraphs arrive
bot_token = '' bot_token = ''
bot_token_secret_arn = os.environ.get('TELEGRAM_BOT_TOKEN_SECRET_ARN', '') bot_token_param = os.environ.get('TELEGRAM_BOT_TOKEN_SSM_PARAM', '')
if bot_token_secret_arn: if bot_token_param:
sm = boto3.client('secretsmanager', region_name='us-east-1') ssm = boto3.client('ssm', region_name='us-east-1')
try: try:
bot_token = sm.get_secret_value(SecretId=bot_token_secret_arn)['SecretString'] bot_token = ssm.get_parameter(Name=bot_token_param, WithDecryption=True)['Parameter']['Value']
except Exception as e: except Exception as e:
print(f'[agent-runner] Failed to get bot token: {e}') print(f'[agent-runner] Failed to get bot token: {e}')

View File

@@ -44,9 +44,10 @@ def get_ddb():
def get_oauth_client() -> tuple[str, str]: def get_oauth_client() -> tuple[str, str]:
"""Return (client_id, client_secret) from Secrets Manager.""" """Return (client_id, client_secret) from SSM Parameter Store."""
arn = os.environ['GOOGLE_OAUTH_CLIENT_SECRET_ARN'] param_name = os.environ['GOOGLE_OAUTH_CLIENT_SSM_PARAM']
secret = json.loads(get_sm().get_secret_value(SecretId=arn)['SecretString']) ssm = boto3.client('ssm', region_name=os.environ.get('AWS_REGION', 'us-east-1'))
secret = json.loads(ssm.get_parameter(Name=param_name, WithDecryption=True)['Parameter']['Value'])
return secret['client_id'], secret['client_secret'] return secret['client_id'], secret['client_secret']
@@ -222,10 +223,11 @@ def handle_callback(params: dict) -> dict:
# Best-effort Telegram confirmation # Best-effort Telegram confirmation
try: try:
bot_token_arn = os.environ.get('TELEGRAM_BOT_TOKEN_SECRET_ARN', '') bot_token_param = os.environ.get('TELEGRAM_BOT_TOKEN_SSM_PARAM', '')
if bot_token_arn and actor_id.startswith('telegram:'): if bot_token_param and actor_id.startswith('telegram:'):
chat_id = actor_id.split(':', 1)[1] chat_id = actor_id.split(':', 1)[1]
bot_token = get_sm().get_secret_value(SecretId=bot_token_arn)['SecretString'] ssm = boto3.client('ssm', region_name=os.environ.get('AWS_REGION', 'us-east-1'))
bot_token = ssm.get_parameter(Name=bot_token_param, WithDecryption=True)['Parameter']['Value']
tg_text = f'✅ Connected {user_email} as "{label}"' tg_text = f'✅ Connected {user_email} as "{label}"'
tg_payload = json.dumps({'chat_id': chat_id, 'text': tg_text}).encode() tg_payload = json.dumps({'chat_id': chat_id, 'text': tg_text}).encode()
tg_req = urllib.request.Request( tg_req = urllib.request.Request(

View File

@@ -11,8 +11,8 @@ def handler(event, context):
rule_name = event['rule_name'] rule_name = event['rule_name']
# Fetch bot token # Fetch bot token
sm = boto3.client('secretsmanager', region_name='us-east-1') ssm = boto3.client('ssm', region_name='us-east-1')
token = sm.get_secret_value(SecretId=os.environ['TELEGRAM_BOT_TOKEN_SECRET_ARN'])['SecretString'] token = ssm.get_parameter(Name=os.environ['TELEGRAM_BOT_TOKEN_SSM_PARAM'], WithDecryption=True)['Parameter']['Value']
# Send Telegram message # Send Telegram message
payload = json.dumps({'chat_id': chat_id, 'text': message}).encode() payload = json.dumps({'chat_id': chat_id, 'text': message}).encode()

View File

@@ -20,10 +20,11 @@ def get_bot_token() -> str:
if _bot_token is None: if _bot_token is None:
with _token_lock: with _token_lock:
if _bot_token is None: if _bot_token is None:
sm = boto3.client('secretsmanager') ssm = boto3.client('ssm')
_bot_token = sm.get_secret_value( _bot_token = ssm.get_parameter(
SecretId=os.environ['TELEGRAM_BOT_TOKEN_SECRET_ARN'] Name=os.environ['TELEGRAM_BOT_TOKEN_SSM_PARAM'],
)['SecretString'] WithDecryption=True
)['Parameter']['Value']
return _bot_token return _bot_token

View File

@@ -1,5 +1,5 @@
""" """
Fetch Google OAuth credentials and client secrets from Secrets Manager. Fetch Google OAuth credentials from SSM (client secret) and Secrets Manager (per-user tokens).
Called by bootstrap before starting workspace-mcp. Called by bootstrap before starting workspace-mcp.
""" """
import json import json
@@ -12,10 +12,11 @@ def main():
sm = boto3.client('secretsmanager', region_name=region) sm = boto3.client('secretsmanager', region_name=region)
# Fetch OAuth client credentials (client_id + client_secret) # Fetch OAuth client credentials (client_id + client_secret)
client_secret_arn = os.environ.get('GOOGLE_OAUTH_CLIENT_SECRET_ARN') client_secret_param = os.environ.get('GOOGLE_OAUTH_CLIENT_SSM_PARAM')
if client_secret_arn: if client_secret_param:
try: try:
client_creds = json.loads(sm.get_secret_value(SecretId=client_secret_arn)['SecretString']) ssm = boto3.client('ssm', region_name=region)
client_creds = json.loads(ssm.get_parameter(Name=client_secret_param, WithDecryption=True)['Parameter']['Value'])
os.environ['GOOGLE_OAUTH_CLIENT_ID'] = client_creds['client_id'] os.environ['GOOGLE_OAUTH_CLIENT_ID'] = client_creds['client_id']
os.environ['GOOGLE_OAUTH_CLIENT_SECRET'] = client_creds['client_secret'] os.environ['GOOGLE_OAUTH_CLIENT_SECRET'] = client_creds['client_secret']
print('[fetch_credentials] OAuth client credentials loaded', file=sys.stderr) print('[fetch_credentials] OAuth client credentials loaded', file=sys.stderr)

View File

@@ -21,11 +21,11 @@ def _setup_shared_environment():
os.environ.setdefault('HOME', '/tmp') os.environ.setdefault('HOME', '/tmp')
os.environ.setdefault('GOOGLE_WORKSPACE_MCP_CREDENTIALS_DIR', '/tmp/workspace_mcp_credentials') os.environ.setdefault('GOOGLE_WORKSPACE_MCP_CREDENTIALS_DIR', '/tmp/workspace_mcp_credentials')
client_arn = os.environ.get('GOOGLE_OAUTH_CLIENT_SECRET_ARN', '') client_param = os.environ.get('GOOGLE_OAUTH_CLIENT_SSM_PARAM', '')
if client_arn: if client_param:
try: try:
sm = boto3.client('secretsmanager', region_name=os.environ.get('AWS_REGION', 'us-east-1')) ssm = boto3.client('ssm', region_name=os.environ.get('AWS_REGION', 'us-east-1'))
client_creds = json.loads(sm.get_secret_value(SecretId=client_arn)['SecretString']) client_creds = json.loads(ssm.get_parameter(Name=client_param, WithDecryption=True)['Parameter']['Value'])
os.environ['GOOGLE_OAUTH_CLIENT_ID'] = client_creds['client_id'] os.environ['GOOGLE_OAUTH_CLIENT_ID'] = client_creds['client_id']
os.environ['GOOGLE_OAUTH_CLIENT_SECRET'] = client_creds['client_secret'] os.environ['GOOGLE_OAUTH_CLIENT_SECRET'] = client_creds['client_secret']
except Exception as e: except Exception as e: