Skip to content

feat: add dev airflow roles & groups for webserver client#191

Merged
sandrahoang686 merged 5 commits intofeat/airflow-webserver-clientfrom
feat/airflow-webserver-fab-roles-and-groups
Feb 19, 2026
Merged

feat: add dev airflow roles & groups for webserver client#191
sandrahoang686 merged 5 commits intofeat/airflow-webserver-clientfrom
feat/airflow-webserver-fab-roles-and-groups

Conversation

@sandrahoang686
Copy link
Contributor

@sandrahoang686 sandrahoang686 commented Feb 18, 2026

Related to: NASA-IMPACT/veda-data-airflow#418, #185

This adds the airflow Admin, Viewer, and Dag_launcher roles and maps them to existing groups in dev.

@github-actions
Copy link

github-actions bot commented Feb 18, 2026

Diff for stage: DefaultStage

Warning

1 Destructive Changes

Diff for stack: veda-keycloak-dev - 0 to add, 3 to update, 0 to destroy

Details

[!WARNING]
Destructive Changes ‼️
Stack: veda-keycloak-dev - Resource: configConfigTaskDef650ED3A2 - Impact: WILL_REPLACE

Resources
[~] AWS::ECS::TaskDefinition configConfigTaskDef650ED3A2 replace
 └─ [~] ContainerDefinitions (requires replacement)
     └─ @@ -28,7 +28,7 @@
        [ ] ],
        [ ] "Essential": true,
        [ ] "Image": {
        [-]   "Fn::Sub": "853558080719.dkr.ecr.us-west-2.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-853558080719-us-west-2:108a527be621fe9c36686c48a1f61cbe18e8406a2a5b5ec910d846948358d99b"
        [+]   "Fn::Sub": "853558080719.dkr.ecr.us-west-2.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-853558080719-us-west-2:c2120f66f2c98393141f72e3b50fa0fe159624134dea4fa7967462b7105cb1e8"
        [ ] },
        [ ] "LogConfiguration": {
        [ ]   "LogDriver": "awslogs",
        @@ -71,13 +71,13 @@
        [ ]   }
        [ ] },
        [ ] {
        [-]   "Name": "GHGC_AIRFLOW_STAC_ETL_CLIENT_ID",
        [+]   "Name": "JUPYTERHUB_MAAP_CLIENT_ID",
        [ ]   "ValueFrom": {
        [ ]     "Fn::Join": [
        [ ]       "",
        [ ]       [
        [ ]         {
        [-]           "Ref": "configghgcairflowstacetlclientsecret51E33BCC"
        [+]           "Ref": "configjupyterhubmaapclientsecretD6DDBC4E"
        [ ]         },
        [ ]         ":id::"
        [ ]       ]
        @@ -85,13 +85,13 @@
        [ ]   }
        [ ] },
        [ ] {
        [-]   "Name": "GHGC_AIRFLOW_STAC_ETL_CLIENT_SECRET",
        [+]   "Name": "JUPYTERHUB_MAAP_CLIENT_SECRET",
        [ ]   "ValueFrom": {
        [ ]     "Fn::Join": [
        [ ]       "",
        [ ]       [
        [ ]         {
        [-]           "Ref": "configghgcairflowstacetlclientsecret51E33BCC"
        [+]           "Ref": "configjupyterhubmaapclientsecretD6DDBC4E"
        [ ]         },
        [ ]         ":secret::"
        [ ]       ]
        @@ -99,34 +99,6 @@
        [ ]   }
        [ ] },
        [ ] {
        [-]   "Name": "GHGC_AIRFLOW_INGEST_API_ETL_CLIENT_ID",
        [-]   "ValueFrom": {
        [-]     "Fn::Join": [
        [-]       "",
        [-]       [
        [-]         {
        [-]           "Ref": "configghgcairflowingestapietlclientsecretE163E385"
        [-]         },
        [-]         ":id::"
        [-]       ]
        [-]     ]
        [-]   }
        [-] },
        [-] {
        [-]   "Name": "GHGC_AIRFLOW_INGEST_API_ETL_CLIENT_SECRET",
        [-]   "ValueFrom": {
        [-]     "Fn::Join": [
        [-]       "",
        [-]       [
        [-]         {
        [-]           "Ref": "configghgcairflowingestapietlclientsecretE163E385"
        [-]         },
        [-]         ":secret::"
        [-]       ]
        [-]     ]
        [-]   }
        [-] },
        [-] {
        [ ]   "Name": "GRAFANA_CLIENT_ID",
        [ ]   "ValueFrom": {
        [ ]     "Fn::Join": [
        @@ -351,13 +323,13 @@
        [ ]   }
        [ ] },
        [ ] {
        [-]   "Name": "JUPYTERHUB_MAAP_CLIENT_ID",
        [+]   "Name": "GHGC_AIRFLOW_STAC_ETL_CLIENT_ID",
        [ ]   "ValueFrom": {
        [ ]     "Fn::Join": [
        [ ]       "",
        [ ]       [
        [ ]         {
        [-]           "Ref": "configjupyterhubmaapclientsecretD6DDBC4E"
        [+]           "Ref": "configghgcairflowstacetlclientsecret51E33BCC"
        [ ]         },
        [ ]         ":id::"
        [ ]       ]
        @@ -365,13 +337,13 @@
        [ ]   }
        [ ] },
        [ ] {
        [-]   "Name": "JUPYTERHUB_MAAP_CLIENT_SECRET",
        [+]   "Name": "GHGC_AIRFLOW_STAC_ETL_CLIENT_SECRET",
        [ ]   "ValueFrom": {
        [ ]     "Fn::Join": [
        [ ]       "",
        [ ]       [
        [ ]         {
        [-]           "Ref": "configjupyterhubmaapclientsecretD6DDBC4E"
        [+]           "Ref": "configghgcairflowstacetlclientsecret51E33BCC"
        [ ]         },
        [ ]         ":secret::"
        [ ]       ]
        @@ -379,6 +351,34 @@
        [ ]   }
        [ ] },
        [ ] {
        [+]   "Name": "GHGC_AIRFLOW_INGEST_API_ETL_CLIENT_ID",
        [+]   "ValueFrom": {
        [+]     "Fn::Join": [
        [+]       "",
        [+]       [
        [+]         {
        [+]           "Ref": "configghgcairflowingestapietlclientsecretE163E385"
        [+]         },
        [+]         ":id::"
        [+]       ]
        [+]     ]
        [+]   }
        [+] },
        [+] {
        [+]   "Name": "GHGC_AIRFLOW_INGEST_API_ETL_CLIENT_SECRET",
        [+]   "ValueFrom": {
        [+]     "Fn::Join": [
        [+]       "",
        [+]       [
        [+]         {
        [+]           "Ref": "configghgcairflowingestapietlclientsecretE163E385"
        [+]         },
        [+]         ":secret::"
        [+]       ]
        [+]     ]
        [+]   }
        [+] },
        [+] {
        [ ]   "Name": "GH_CLIENT_ID",
        [ ]   "ValueFrom": "arn:aws:secretsmanager:us-west-2:853558080719:secret:veda-keycloak-gh-oauth-creds-dXqTIU:id::"
        [ ] },
[~] AWS::IAM::Policy configConfigTaskDefExecutionRoleDefaultPolicyB2F7D3D0
 └─ [~] PolicyDocument
     └─ [~] .Statement:
         └─ @@ -54,7 +54,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configghgcairflowstacetlclientsecret51E33BCC"
            [+]     "Ref": "configjupyterhubmaapclientsecretD6DDBC4E"
            [ ]   }
            [ ] },
            [ ] {
            @@ -64,7 +64,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configghgcairflowingestapietlclientsecretE163E385"
            [+]     "Ref": "configgrafanaclientsecretA8C7647C"
            [ ]   }
            [ ] },
            [ ] {
            @@ -74,7 +74,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configgrafanaclientsecretA8C7647C"
            [+]     "Ref": "configairflowstacetlclientsecret4D03E787"
            [ ]   }
            [ ] },
            [ ] {
            @@ -84,7 +84,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configairflowstacetlclientsecret4D03E787"
            [+]     "Ref": "configairflowingestapietlclientsecret9171EF20"
            [ ]   }
            [ ] },
            [ ] {
            @@ -94,7 +94,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configairflowingestapietlclientsecret9171EF20"
            [+]     "Ref": "configjupyterhubdisastersclientsecret7640859E"
            [ ]   }
            [ ] },
            [ ] {
            @@ -104,7 +104,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configjupyterhubdisastersclientsecret7640859E"
            [+]     "Ref": "configingestuiclientsecretFE3C4C92"
            [ ]   }
            [ ] },
            [ ] {
            @@ -114,7 +114,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configingestuiclientsecretFE3C4C92"
            [+]     "Ref": "configdiscourseforumclientsecretBF20DC0A"
            [ ]   }
            [ ] },
            [ ] {
            @@ -124,7 +124,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configdiscourseforumclientsecretBF20DC0A"
            [+]     "Ref": "configumaresourceserverclientsecret18087D88"
            [ ]   }
            [ ] },
            [ ] {
            @@ -134,7 +134,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configumaresourceserverclientsecret18087D88"
            [+]     "Ref": "configearthgovcmsclientsecret90151005"
            [ ]   }
            [ ] },
            [ ] {
            @@ -144,7 +144,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configearthgovcmsclientsecret90151005"
            [+]     "Ref": "configghgcairflowstacetlclientsecret51E33BCC"
            [ ]   }
            [ ] },
            [ ] {
            @@ -154,7 +154,7 @@
            [ ]   ],
            [ ]   "Effect": "Allow",
            [ ]   "Resource": {
            [-]     "Ref": "configjupyterhubmaapclientsecretD6DDBC4E"
            [+]     "Ref": "configghgcairflowingestapietlclientsecretE163E385"
            [ ]   }
            [ ] },
            [ ] {
[~] AWS::CloudFormation::Stack sesrelayNestedStacksesrelayNestedStackResource3873FD90
 └─ [~] TemplateURL
     └─ [~] .Fn::Join:
         └─ @@ -5,6 +5,6 @@
            [ ]     {
            [ ]       "Ref": "AWS::URLSuffix"
            [ ]     },
            [-]     "/cdk-hnb659fds-assets-853558080719-us-west-2/c6c8e5c99a03a9ca805f8f7bea079772bac095cd69c9f584486ece55a27c407d.json"
            [+]     "/cdk-hnb659fds-assets-853558080719-us-west-2/a1575ac7d3275ccb5db957093b3c9487636544642eda51ffb759c5fe9ac46353.json"
            [ ]   ]
            [ ] ]

Generated for commit 5f0c1e1 at 2026-02-19T18:52:29.453Z

- name: Viewer
description: Limited read permissions
- name: Dag_Launcher
description: Programmatic DAG runs
Copy link
Contributor Author

@sandrahoang686 sandrahoang686 Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗒️ : I've stripped the pre-fix airflow-* and just used the same pattern we currently have for other roles and from the airflow docs. I'm aware that these are mapped like so - here though. Hopefully this is okay?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine but would need to be reflected in the mapping you linked as well

- Editor
airflow-webserver-fab:
- Admin
- Dag_Launcher
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was unsure how to map Dag_Launcher, lmk if it should be mapped elsewhere.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should map it to a service account, and make sure we adjust the scripts in veda-data before we push the keycloak changes to prod.

By setting serviceAccountsEnabled: true on the client, we can add a service account like this:

users:
  - username: service-account-airflow-webserver-fab
    emailVerified: true
    enabled: true
    serviceAccountClientId: airflow-webserver-fab
    clientRoles:
      airflow-webserver-fab:
        - Dag_Launcher

The auth flow for our automated scripts will then look like this:

token_url = "https://<keycloak>/realms/veda/protocol/openid-connect/token"
client_id = "airflow-webserver-fab"
client_secret = "<secret>"  # get this from the keycloak console after deployment

resp = requests.post(token_url, data={
    "grant_type": "client_credentials",
    "client_id": client_id,
    "client_secret": client_secret
})
token = resp.json()["access_token"]

headers = {"Authorization": f"Bearer {token}"}

@sandrahoang686 sandrahoang686 marked this pull request as ready for review February 18, 2026 16:24
@sandrahoang686
Copy link
Contributor Author

Also - how do i test this?? is there a way to manually deploy?

Copy link
Contributor

@smohiudd smohiudd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sandrahoang686 sandrahoang686 merged commit 9aa6f4b into feat/airflow-webserver-client Feb 19, 2026
1 check passed
@sandrahoang686 sandrahoang686 deleted the feat/airflow-webserver-fab-roles-and-groups branch February 19, 2026 18:54
ividito added a commit that referenced this pull request Feb 19, 2026
* feat: add dev airflow client for webserver auth testing

* feat: add dev airflow roles & groups for webserver client (#191)

* add roles

* map roles to groups

* update to pr comments

* set airflow-webserver client serviceAccountsEnabled to true

* Add User perms

---------

Co-authored-by: sandrahoang686 <sandrahoang686@gmail.com>
Co-authored-by: Saadiq Mohiuddin <34844565+smohiudd@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments