Skip to main content
Glama
setup_spn_secret_access.py•5.08 kB
#!/usr/bin/env python3 """ Setup Service Principal access to Databricks Secrets. This script grants the app's SPN access to the 'dataverse' secret scope so it can read credentials when running as a Databricks App. Usage: export DATABRICKS_HOST="https://your-workspace.azuredatabricks.net" export DATABRICKS_TOKEN="your-token" python setup_spn_secret_access.py """ import os from databricks.sdk import WorkspaceClient from databricks.sdk.service.workspace import AclPermission # SPN for the Databricks App APP_SPN_ID = "8e80703e-902e-4164-b195-80692ba6fce1" SECRET_SCOPE = "dataverse" def main(): print("=" * 60) print("Setup SPN Secret Access") print("=" * 60) print() # Initialize workspace client from environment variables print("šŸ” Connecting to Databricks workspace...") print(f" Host: {os.getenv('DATABRICKS_HOST', '(using default profile)')}") w = WorkspaceClient() # Uses DATABRICKS_HOST and DATABRICKS_TOKEN from env or ~/.databrickscfg print("āœ… Connected to Databricks") print() # Check if secret scope exists print(f"šŸ” Checking secret scope '{SECRET_SCOPE}'...") try: scopes = list(w.secrets.list_scopes()) scope_names = [s.name for s in scopes] if SECRET_SCOPE not in scope_names: print(f"āŒ Secret scope '{SECRET_SCOPE}' does not exist!") print() print("Please create it first:") print(f" databricks secrets create-scope {SECRET_SCOPE}") print() print("Or run: ./setup_databricks_secrets.sh") return 1 print(f"āœ… Secret scope '{SECRET_SCOPE}' exists") except Exception as e: print(f"āŒ Error checking scopes: {e}") return 1 print() # List current ACLs print(f"šŸ“‹ Current ACLs for scope '{SECRET_SCOPE}':") try: acls = list(w.secrets.list_acls(scope=SECRET_SCOPE)) if acls: for acl in acls: print(f" - Principal: {acl.principal}, Permission: {acl.permission}") else: print(" (No ACLs - scope creator has full access)") except Exception as e: print(f" āš ļø Could not list ACLs: {e}") print() # Grant SPN access print(f"šŸ”‘ Granting MANAGE permission to SPN {APP_SPN_ID}...") try: w.secrets.put_acl( scope=SECRET_SCOPE, principal=APP_SPN_ID, permission=AclPermission.MANAGE ) print("āœ… Successfully granted MANAGE permission") except Exception as e: print(f"āŒ Error granting permission: {e}") print() print("This might happen if:") print(" 1. The SPN already has access (this is fine)") print(" 2. You don't have permission to modify ACLs") print(" 3. The secret scope is workspace-level and ACLs are managed differently") print() print("Trying with CLI command instead...") import subprocess try: result = subprocess.run( ["databricks", "secrets", "put-acl", SECRET_SCOPE, APP_SPN_ID, "MANAGE"], capture_output=True, text=True, check=True ) print("āœ… Successfully granted MANAGE permission via CLI") except subprocess.CalledProcessError as cli_error: print(f"āŒ CLI command also failed: {cli_error}") return 1 print() # Verify access print("šŸ” Verifying SPN has access...") try: acls = list(w.secrets.list_acls(scope=SECRET_SCOPE)) spn_acl = next((a for a in acls if a.principal == APP_SPN_ID), None) if spn_acl: print(f"āœ… SPN has {spn_acl.permission} permission") else: print("āš ļø SPN not found in ACL list, but this might be OK if scope is workspace-level") except Exception as e: print(f"āš ļø Could not verify: {e}") print() # List secrets in scope print(f"šŸ“‹ Secrets in scope '{SECRET_SCOPE}':") try: secrets = list(w.secrets.list_secrets(scope=SECRET_SCOPE)) if secrets: for secret in secrets: print(f" - {secret.key}") print() print(f"āœ… Found {len(secrets)} secret(s)") else: print(" (No secrets found)") print() print("āš ļø You need to create secrets first:") print(" ./setup_databricks_secrets.sh") except Exception as e: print(f"āŒ Error listing secrets: {e}") return 1 print() print("=" * 60) print("āœ… Setup Complete!") print("=" * 60) print() print("Next steps:") print(" 1. Make sure secrets are populated: ./setup_databricks_secrets.sh") print(" 2. Remove hardcoded fallback credentials from server/dataverse/auth.py") print(" 3. Redeploy the app: ./deploy.sh") print() return 0 if __name__ == "__main__": exit(main())

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lucamilletti99/dataverse_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server