From dab2a2b37ccfc41a9ba79de17f7d8c09f841b319 Mon Sep 17 00:00:00 2001
From: Isayah Vidito <isayah@developmentseed.org>
Date: Tue, 22 Aug 2023 10:32:35 -0400
Subject: [PATCH] Add configurable role access to credential flow secrets

---
 app.py         | 2 ++
 config.py      | 7 ++++++-
 infra/stack.py | 7 +++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/app.py b/app.py
index a15f1ac..de56ca7 100644
--- a/app.py
+++ b/app.py
@@ -104,6 +104,8 @@
         oidc_thumbprint,
     )
 
+
+
 # Programmatic Clients
 stack.add_programmatic_client("veda-sdk")
 
diff --git a/config.py b/config.py
index a9e3485..c545d91 100644
--- a/config.py
+++ b/config.py
@@ -1,5 +1,5 @@
 from getpass import getuser
-from typing import Optional
+from typing import Optional, Sequence
 
 import pydantic
 
@@ -39,3 +39,8 @@ class Config(pydantic.BaseSettings):
         None,
         description="Thumbprint of OIDC provider to use for CI workers.",
     )
+
+    secret_role_access: Sequence[str] = pydantic.Field(
+        [],
+        description="Optional list of role ARNs with access to credential flow secrets"
+    )
\ No newline at end of file
diff --git a/infra/stack.py b/infra/stack.py
index 10855ab..8133afc 100644
--- a/infra/stack.py
+++ b/infra/stack.py
@@ -186,6 +186,7 @@ def _create_secret(
         self,
         service_id: str,
         secret_dict: Dict[Any, Any],
+        secret_role_access: Sequence[str] = []  # list of roles with access to get secret value
     ):
         """
         Create a secret to represent service credentials.
@@ -203,6 +204,10 @@ def _create_secret(
             # CloudFormation template.
             secret_string_value=SecretValue.unsafe_plain_text(json.dumps(secret_dict)),
         )
+        
+        for role_arn in secret_role_access:
+            role = iam.Role.from_role_arn(self, f"ImportedRole{role_arn.split(':')[-1]}", role_arn)
+            secret.grant_read(role)
 
         CfnOutput(
             self,
@@ -296,6 +301,7 @@ def add_programmatic_client(
         self,
         service_id: str,
         name: Optional[str] = None,
+        secret_role_access: Optional[str] = []  # Optional role arns with access to auth flow secret
     ) -> cognito.UserPoolClient:
 
         client = self.userpool.add_client(
@@ -313,6 +319,7 @@ def add_programmatic_client(
                 "cognito_domain": self.domain.base_url(),
                 "client_id": client.user_pool_client_id,
             },
+            secret_role_access,
         )
 
         return client