Skip to content

Commit

Permalink
Change tools-tests workflow to use federated credential instead of cl…
Browse files Browse the repository at this point in the history
…ient secret (microsoft#3077)

Change tools-tests workflow to use federated credential instead of
client secret:
1. In tools_tests.yml file to add permission section for id_token and
content, this setting allows the JWT to be requested from GitHub's OIDC
provider.
2. Add azure/login@v1 to az login using federated credential;
3. Using AzureCliCredential instead of ClientSecretCredential to init
SecretClient.

workflow test link:
https://github.com/microsoft/promptflow/actions/runs/8888730637

Delete the tools_secret_upload workflow since it is useless now.

---------

Co-authored-by: Ge Gao <[email protected]>
  • Loading branch information
dorisjoy and gegao-MS authored May 6, 2024
1 parent 637ad8a commit e392e87
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 213 deletions.
70 changes: 0 additions & 70 deletions .github/workflows/tools_secret_upload.yml

This file was deleted.

20 changes: 17 additions & 3 deletions .github/workflows/tools_tests.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
name: tools_tests
permissions:
# This is required for requesting the JWT
id-token: write
# This is required for actions/checkout
contents: read
on:
workflow_dispatch:
pull_request_target:
paths:
- src/promptflow-tools/**
- '**tools_tests.yml'
workflow_dispatch:
- scripts/tool/**
- .github/workflows/tools_tests.yml
jobs:
authorize:
environment:
Expand Down Expand Up @@ -53,9 +59,17 @@ jobs:
pip install azure-mgmt-cognitiveservices==13.5.0
fi
pip list
- name: Azure login
uses: azure/login@v1
with:
client-id: ${{ secrets.CLIENT_ID }}
tenant-id: ${{ secrets.TENANT_ID }}
subscription-id: ${{ secrets.TEST_WORKSPACE_SUB_ID }}

- name: Generate configs
run: |
python ./scripts/tool/generate_connection_config.py --tenant_id ${{ secrets.TENANT_ID }} --client_id ${{ secrets.CLIENT_ID }} --client_secret ${{ secrets.CLIENT_SECRET }}
python ./scripts/tool/generate_connection_config.py
- name: Run tests
run: |
Expand Down
5 changes: 1 addition & 4 deletions scripts/tool/generate_connection_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ def fill_key_to_dict(template_dict, keys_dict):

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--tenant_id", type=str, help="The tenant id of the service principal")
parser.add_argument("--client_id", type=str, help="The client id of the service principal")
parser.add_argument("--client_secret", type=str, help="The client secret of the service principal")
parser.add_argument("--local", action='store_true', help="local debug mode")
args = parser.parse_args()

Expand All @@ -32,7 +29,7 @@ def fill_key_to_dict(template_dict, keys_dict):
print(f"file_path: {file_path}")

if not args.local:
client = get_secret_client(tenant_id=args.tenant_id, client_id=args.client_id, client_secret=args.client_secret)
client = get_secret_client()
all_secret_names = list_secret_names(client)
data = {secret_name: get_secret(secret_name, client) for secret_name in all_secret_names}

Expand Down
41 changes: 0 additions & 41 deletions scripts/tool/upload_tool_secret.py

This file was deleted.

59 changes: 3 additions & 56 deletions scripts/tool/utils/secret_manager.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
import re

from azure.core.exceptions import HttpResponseError, ResourceExistsError
from azure.identity import ClientSecretCredential
from azure.identity import AzureCliCredential
from azure.keyvault.secrets import SecretClient
from exceptions import (
SecretNameAlreadyExistsException,
SecretNameInvalidException,
SecretNoSetPermissionException,
)

key_vault_name = "github-promptflow"
container_name = "tools"
KVUri = f"https://{key_vault_name}.vault.azure.net"


def init_used_secret_names(client: SecretClient):
global reserved_secret_names
reserved_secret_names = list_secret_names(client)


def get_secret_client(
tenant_id: str, client_id: str, client_secret: str
) -> SecretClient:
credential = ClientSecretCredential(tenant_id, client_id, client_secret)
def get_secret_client() -> SecretClient:
credential = AzureCliCredential()
client = SecretClient(vault_url=KVUri, credential=credential)

return client


reserved_secret_names = []


def get_secret(secret_name: str, client: SecretClient):
secret = client.get_secret(secret_name)

Expand All @@ -41,37 +22,3 @@ def list_secret_names(client: SecretClient) -> list:
secret_properties = client.list_properties_of_secrets()

return [secret.name for secret in secret_properties]


def validate_secret_name(secret_name: str):
# Check if secret name is valid. Secret name can only contain alphanumeric characters and dashes.
pattern = "^[a-zA-Z0-9-]+$"
if not re.match(pattern, secret_name):
raise SecretNameInvalidException(
"Secret name can only contain alphanumeric characters and dashes"
)
# Check if secret name is one of the reserved names
if secret_name in reserved_secret_names:
raise SecretNameAlreadyExistsException(
f"Secret name {secret_name} already exists"
)


def upload_secret(client: SecretClient, secret_name: str, secret_value: str):
try:
client.set_secret(secret_name, secret_value)
except ResourceExistsError as ex:
if "in a deleted but recoverable state" in str(ex):
raise SecretNameAlreadyExistsException(
f"Secret name {secret_name} is deleted but recoverable, and its name cannot be reused"
)
except HttpResponseError as ex:
if (
ex.status_code == 403
and "does not have secrets set permission on key vault" in str(ex)
):
raise SecretNoSetPermissionException(
f"No set permission on key vault {key_vault_name}"
)

print("Done.")
39 changes: 0 additions & 39 deletions scripts/tool/validate_tool_secret.py

This file was deleted.

0 comments on commit e392e87

Please sign in to comment.