For the complete documentation index, see llms.txt. This page is also available as Markdown.

Azure SQL — Managed Identity

Configure Azure SQL scanning using a User Assigned Managed Identity (UAMI) instead of a SQL login and password. Use this path when your security policy prohibits stored credentials, or when Teleskope runs in your Azure subscription with Workload Identity. For the standard SQL login setup, see Azure SQL.

Requirements

  • Teleskope scanning services run in your Azure subscription with Workload Identity enabled and a UAMI attached

  • Microsoft Entra authentication is enabled on each Azure SQL server (an Entra admin is set on the server)

  • You have az CLI access to the resource group containing the UAMI, and admin access to the SQL servers

This page applies to Azure SQL Database (*.database.windows.net). SQL Server running on Azure VMs requires instance-level Entra configuration and is not covered here.

Identify the managed identity

Database users must be bound to the exact identity the Teleskope pods run as. Look it up by its client ID (provided by Teleskope, visible in the pod environment as AZURE_CLIENT_ID):

az identity list -g <resource-group> \
  --query "[?clientId=='<client-id>'].{name:name, principalId:principalId}" -o table

Record the identity name and principalId. If CREATE USER [<name>] FROM EXTERNAL PROVIDER later fails with "Principal not found in the directory", create the user by object ID instead:

CREATE USER [teleskope-identity] FROM EXTERNAL PROVIDER WITH OBJECT_ID = '<principalId>';

Permissions

1

Create the identity user in master

Entra identities are contained database users; unlike a SQL login, they have no server-level principal. Teleskope's first connection to each server lands in master to enumerate databases, so the identity needs a user there:

-- in master
CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER;
GRANT VIEW ANY DATABASE TO [<identity-name>];

VIEW ANY DATABASE makes the database enumeration return all databases on the server. This is the managed-identity equivalent of the GRANT VIEW ANY DATABASE step in the standard setup; it is explicit here because Entra users must be created per database. Do not add db_datareader in master — no table data is read there.

2

Grant read access in each database

For each database to be scanned:

Azure SQL Database does not support cross-database USE, so the grants run per database. To avoid manual repetition, loop over the server's databases from a client with az CLI and sqlcmd, authenticated as an Entra admin of the server (-G uses Entra authentication):

SERVER='<server-name>'            # without .database.windows.net
RG='<resource-group>'
IDENTITY='<identity-name>'

# once per server: master user + enumeration grant
sqlcmd -S "$SERVER.database.windows.net" -d master -G -Q "
  IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = '$IDENTITY')
    CREATE USER [$IDENTITY] FROM EXTERNAL PROVIDER;
  GRANT VIEW ANY DATABASE TO [$IDENTITY];"

# every database on the server: read grants
for DB in $(az sql db list --server "$SERVER" -g "$RG" --query "[?name!='master'].name" -o tsv); do
  sqlcmd -S "$SERVER.database.windows.net" -d "$DB" -G -Q "
    IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = '$IDENTITY')
      CREATE USER [$IDENTITY] FROM EXTERNAL PROVIDER;
    GRANT SELECT TO [$IDENTITY];
    GRANT VIEW DATABASE STATE TO [$IDENTITY];"
done

The script is idempotent and safe to re-run; wrap it in an outer loop over az sql server list to cover every server. To grant a single database manually, run just the inner statements connected to that database:

These are the same read grants as the standard setup: SELECT for table contents, VIEW DATABASE STATE for row-count statistics.

3

Verify the identity binding

Confirm the database user is bound to the identity Teleskope runs as. In any database where the user was created:

SELECT name, CONVERT(uniqueidentifier, sid) AS client_id
FROM sys.database_principals
WHERE name = '<identity-name>';

client_id must equal the UAMI client ID from the identification step. A different value means the user is bound to another principal; drop it and recreate with WITH OBJECT_ID.

4

Validate on one server, then roll out

Apply the master and per-database grants on a single server, trigger a scan, and confirm its databases and tables appear in the Teleskope catalog. Repeat for the remaining servers.

Last updated

Was this helpful?