Locked SQL Server database with a key and a sealed envelope, representing an encrypted database scoped credential

SQL Server DATABASE SCOPED CREDENTIAL: Setup, Permissions, Restores and Always On

How DATABASE SCOPED CREDENTIAL keeps API keys and SAS tokens out of your code, and how to handle master keys, permissions, rotation, restores and Always On without surprises.

November 9, 2026

Every time SQL Server reaches outside itself it needs a credential: reading files from Azure Blob Storage, calling a REST API, querying another source through PolyBase, or connecting to an embedding model in SQL Server 2025. A DATABASE SCOPED CREDENTIAL stores that identity and secret encrypted inside the database, so API keys and passwords never have to appear in your code. Get the master key, permissions, restores or Always On wrong, though, and it fails in production at the worst possible moment.

This guide covers DATABASE SCOPED CREDENTIAL end to end: prerequisites, creation, permissions, secret rotation, inventory, restoring to another server and Always On. The error messages and results in this guide come from our tests on SQL Server 2025.

SQL Server Consulting

Let's review your credentials and encryption keys together

Aryasoft reviews the credentials, master keys and permissions in your SQL Server estate and sets them up so migrations and disaster recovery don't break them.

SQL Server Services

Quick Summary

Topic Summary
What it does Stores, encrypted, the identity and secret a database uses to authenticate to an external resource.
Where it lives In the user database. It travels with the database backup.
Prerequisite A database master key (DMK). Without one you get Msg 15581.
Permission to create CONTROL on the database
Permission to use REFERENCES on the credential (for example for REST calls)
Used by PolyBase and external data sources, BULK INSERT / OPENROWSET from Blob, sp_invoke_external_rest_endpoint, CREATE EXTERNAL MODEL, and in Azure SQL Database elastic query and the Extended Events file target
Not used by BACKUP TO URL and SQL Agent proxies: these use server-level CREATE CREDENTIAL.

What Is a DATABASE SCOPED CREDENTIAL?

A DATABASE SCOPED CREDENTIAL is the identity a database uses to connect to an external resource. It has two parts: IDENTITY (an account name or an authentication type) and SECRET (a password, SAS token or API key). It isn’t mapped to a login or a database user. The database uses it whenever it performs an operation that needs outside access.

The secret isn’t stored in plain text; it’s encrypted with the database master key. Catalog views show only the credential’s name and identity, and there’s no way to read the secret back. That means API keys don’t have to live in stored procedure code, Agent job steps or application configuration.

How It Differs from a Server Credential

SQL Server has two kinds of credentials, and they’re often confused:

Property CREATE CREDENTIAL (server) CREATE DATABASE SCOPED CREDENTIAL
Stored in master, sys.credentials The user database, sys.database_scoped_credentials
Travels with backups? No, create it on every server Yes, it’s inside the database backup
Typical use BACKUP TO URL, Agent proxies, EKM PolyBase, BULK INSERT / OPENROWSET, REST calls, external models
Prerequisite None Database master key
Permission to create ALTER ANY CREDENTIAL CONTROL on the database

Because it’s database-level, the credential moves with the application: restore the database on another server and the credentials come along. The master key that decrypts their secrets still has to be openable on the new server, though. We cover that separately below.

Where It’s Used

  • PolyBase and data virtualization: CREATE EXTERNAL DATA SOURCE pointing to another SQL Server, Oracle, an ODBC source or S3-compatible storage
  • Bulk loads from Blob: reading files in Azure Blob Storage with BULK INSERT and OPENROWSET(BULK...)
  • REST API calls: sending an API key as a header or query parameter with sp_invoke_external_rest_endpoint in SQL Server 2025
  • AI models: connecting to an embedding service such as Azure OpenAI with CREATE EXTERNAL MODEL in SQL Server 2025
  • Azure SQL Database: elastic query, writing Extended Events files to Blob, and data virtualization

1. Prerequisite: the Database Master Key

The credential’s secret is encrypted with the database master key. Without a master key, you can’t create a credential:

▤ Messages

Msg 15581: Please create a master key in the database or open the master key in the session before performing this operation.

Check whether a master key exists, and create one with a strong password if it doesn’t:

USE SalesDB;
GO
SELECT name, create_date
FROM sys.symmetric_keys
WHERE name = N'##MS_DatabaseMasterKey##';
GO
IF NOT EXISTS (SELECT 1 FROM sys.symmetric_keys WHERE name = N'##MS_DatabaseMasterKey##')
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'<strong-unique-password>';
GO

When SQL Server creates the master key, it also encrypts it with the instance’s service master key. On the same server the master key then opens automatically, and you don’t need the password day to day. You need the password when the database moves to another server. Keep it in your enterprise password vault and back up the key itself:

BACKUP MASTER KEY TO FILE = N'D:\KeyBackup\SalesDB_dmk.key'
    ENCRYPTION BY PASSWORD = N'<backup-file-password>';

2. Creating a Credential

The syntax is short:

CREATE DATABASE SCOPED CREDENTIAL credential_name
WITH IDENTITY = 'identity',
     SECRET = 'secret-value';

The IDENTITY value depends on the feature that will use the credential:

Scenario IDENTITY SECRET Platform
Azure Blob, SAS token SHARED ACCESS SIGNATURE SAS token (without the leading ?) SQL Server 2022+, Azure SQL, Managed Instance
Azure resources, managed identity Managed Identity None Azure SQL, Managed Instance, SQL Server 2025 with Azure Arc
S3-compatible storage S3 Access Key accesskey:secretkey SQL Server 2022+
REST API, key in a header HTTPEndpointHeaders JSON: {"x-api-key":"..."} SQL Server 2025, Azure SQL
REST API, key in the query string HTTPEndpointQueryString JSON: {"code":"..."} SQL Server 2025, Azure SQL
PolyBase to SQL Server, Oracle, ODBC User name on the remote system Password SQL Server 2019+

Note

A SAS token copied from the Azure portal often starts with ?. Remove that character before storing it in the credential, or access to Blob fails. If the token will be used with PolyBase external tables, allow both Container and Object as resource types.

Example: a REST API Key

When you call an API from SQL Server 2025, put the key in a credential instead of the code. For REST calls the credential name must be a URL that covers the endpoint you call, at the same or a more general path:

CREATE DATABASE SCOPED CREDENTIAL [https://api.example.com/v1]
WITH IDENTITY = 'HTTPEndpointHeaders',
     SECRET = '{"x-api-key":"<api-key>"}';
GO
DECLARE @ret int, @response nvarchar(max);
EXEC @ret = sys.sp_invoke_external_rest_endpoint
     @url = N'https://api.example.com/v1/rates',
     @method = N'GET',
     @credential = [https://api.example.com/v1],
     @response = @response OUTPUT;
SELECT @ret AS http_result, @response AS response;

In our test SQL Server added the credential’s x-api-key value to the request header itself; the key never appeared in the code or the call history. We cover the feature in full in calling REST APIs from SQL Server 2025.

Example: Loading a File from Azure Blob

To load a CSV file from Blob Storage, define a credential with a SAS token, then an external data source that uses it:

CREATE DATABASE SCOPED CREDENTIAL BlobImportCred
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
     SECRET = 'sv=2024-11-04&ss=b&srt=co&sp=rl&se=2027-01-01T00:00:00Z&sig=<signature>';
GO
CREATE EXTERNAL DATA SOURCE BlobImports
WITH (TYPE = BLOB_STORAGE,
      LOCATION = 'https://<account>.blob.core.windows.net/imports',
      CREDENTIAL = BlobImportCred);
GO
BULK INSERT dbo.DailyOrders
FROM 'orders/2026-11-15.csv'
WITH (DATA_SOURCE = 'BlobImports', FORMAT = 'CSV', FIRSTROW = 2);

The file path in FROM is relative to the external data source’s LOCATION. Generate the SAS token with only the permissions you need (read and list) and an expiry date.

3. Permissions

Three separate permissions govern a credential:

Action Required permission
Create CONTROL on the database
Use REFERENCES on the credential
Change ALTER on the credential

Granting EXECUTE ANY EXTERNAL ENDPOINT to a REST caller isn’t enough; it also needs REFERENCES on the credential it uses. In our test, without that permission the user couldn’t even see the credential:

▤ Messages

Msg 15151: Cannot find the credential ‘https://httpbin.org/anything’, because it does not exist or you do not have permission.

Grant the permission for that credential only:

GRANT REFERENCES ON DATABASE SCOPED CREDENTIAL::[https://api.example.com/v1] TO rest_caller;

A user with REFERENCES can use the credential and see its name, but can’t read the secret or change the credential. In our test the same user’s ALTER attempt was rejected with Msg 15151 too. This query lists who has which permission on which credential:

SELECT pr.name AS grantee,
       p.permission_name,
       p.state_desc,
       c.name AS credential_name
FROM sys.database_permissions AS p
JOIN sys.database_scoped_credentials AS c
    ON p.class_desc = N'DATABASE_SCOPED_CREDENTIAL'
   AND p.major_id = c.credential_id
JOIN sys.database_principals AS pr
    ON pr.principal_id = p.grantee_principal_id
ORDER BY c.name, pr.name;

4. Rotating the Secret

API keys and SAS tokens should be rotated regularly. Use ALTER DATABASE SCOPED CREDENTIAL; dependent objects don’t need to change, and external data sources and procedures keep using the same credential name:

ALTER DATABASE SCOPED CREDENTIAL [https://api.example.com/v1]
WITH IDENTITY = 'HTTPEndpointHeaders',
     SECRET = '{"x-api-key":"<new-api-key>"}';

In our test the new key was used on the very next call, with no reconnect or cache flush.

Warning

IDENTITY is mandatory in ALTER, and every ALTER resets both the identity and the secret. Leave out SECRET and the secret becomes NULL, which stops everything that uses the credential. In our test the REST call then failed with Msg 33047: Fail to obtain or decrypt secret for credential. Always write the full statement and make a test call right after it.

The modify_date column shows when each secret was last changed. This query lists credentials older than 90 days:

SELECT name,
       credential_identity,
       create_date,
       modify_date,
       DATEDIFF(DAY, modify_date, SYSDATETIME()) AS days
FROM sys.database_scoped_credentials
WHERE modify_date < DATEADD(DAY, -90, SYSDATETIME())
ORDER BY modify_date;

5. Inventory: Which Credential Is Used Where?

Before dropping a credential or changing its secret, find out what depends on it. External data sources and SQL Server 2025 external models reference the credential by ID:

SELECT c.name AS credential_name,
       c.credential_identity,
       N'EXTERNAL DATA SOURCE' AS used_by_type,
       ds.name AS used_by,
       ds.location
FROM sys.database_scoped_credentials AS c
JOIN sys.external_data_sources AS ds ON ds.credential_id = c.credential_id
UNION ALL
SELECT c.name, c.credential_identity, N'EXTERNAL MODEL', m.name, m.location
FROM sys.database_scoped_credentials AS c
JOIN sys.external_models AS m ON m.credential_id = c.credential_id
ORDER BY credential_name;

REST calls name the credential inside procedure code, so they don’t show up above. Search module definitions for them:

SELECT OBJECT_SCHEMA_NAME(m.object_id) AS schema_name,
       OBJECT_NAME(m.object_id) AS object_name
FROM sys.sql_modules AS m
WHERE m.definition LIKE N'%@credential%';

SQL Server won’t let you drop a credential that’s in use:

▤ Messages

Msg 33164: Cannot drop the credential ‘BlobCred’ because it is used by an external data source.

Drop the dependent external data source first, or point it at another credential. REST calls have no such protection: if the credential is dropped, the procedure fails on its next call.

6. Restoring to Another Server

Because the credential lives in the database, it travels with the backup. The catch is that the master key that decrypts the secret is encrypted with the old server’s service master key, and the new server can’t open it automatically. The credential still shows up in the list, but the first operation that uses it fails.

We reproduced this on our test server by restoring the backup and removing the master key’s server encryption. The credential was still in sys.database_scoped_credentials, but the REST call returned:

▤ Messages

Msg 15581: Please create a master key in the database or open the master key in the session before performing this operation.

The message says “create a master key”, but that isn’t the fix. A new master key can’t decrypt the existing secrets. Open the existing master key with its password and add encryption by the new server’s service master key:

USE SalesDB;
GO
OPEN MASTER KEY DECRYPTION BY PASSWORD = N'<master-key-password>';
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY;
CLOSE MASTER KEY;
GO

After that the master key opens automatically on the new server and the credentials work. In our test the same call succeeded right after these statements. This query shows which databases on a server are missing the step:

SELECT d.name,
       d.is_master_key_encrypted_by_server
FROM sys.databases AS d
WHERE d.database_id > 4
  AND d.is_master_key_encrypted_by_server = 0;

It also lists databases that have no master key at all; for each result, check sys.symmetric_keys for ##MS_DatabaseMasterKey##. Add this check to your migration and upgrade runbooks. For planning a server move, see our SQL Server 2025 upgrade guide.

Critical

If the master key password is lost and the database has to move to another server, the secrets in its credentials can’t be recovered; every credential has to be recreated. On the other hand, a database backup contains the encrypted secrets: anyone with both the backup and the master key password can use them. Keep the password in a vault, encrypt your backups and restrict access to them. See SQL Server backup safety for details.

7. Always On Availability Groups

In an availability group, credentials replicate to the secondaries along with the database; you don’t create them on each replica. The master key, however, is encrypted with the primary’s service master key. After a failover the new primary can’t open it with its own service master key, and anything that uses a credential fails with Msg 15581. Because the secondary database is read-only, you can’t run the ALTER MASTER KEY step there in advance.

That’s what sp_control_dbmasterkey_password is for. Run it once on each secondary replica, and the master key password is stored in that server’s credential store:

USE master;
GO
EXEC sp_control_dbmasterkey_password
     @db_name  = N'SalesDB',
     @password = N'<master-key-password>',
     @action   = N'add';
GO

When SQL Server can’t open a master key with the service master key, it tries the stored passwords for the same database family. If one works, it re-encrypts the master key with the local service master key. On our test server we removed the master key’s server encryption and added this entry: the credential worked, and is_master_key_encrypted_by_server went back to 1 on its own.

Microsoft adds a warning: this entry lets sa and other highly privileged accounts open the master key. Don’t use it for databases whose key hierarchy you deliberately separated from the service master key so that even sysadmins can’t decrypt them. For replica maintenance and failover planning, see our SQL Server Always On guide.

8. Managed Identity in SQL Server 2025

SQL Server 2025 supports Microsoft Entra managed identities on servers connected through Azure Arc. The credential then has no secret: the server’s Azure identity authenticates, and there’s no key left to rotate:

EXEC sp_configure 'allow server scoped db credentials', 1;
RECONFIGURE;
GO
CREATE DATABASE SCOPED CREDENTIAL [https://<account>.blob.core.windows.net]
WITH IDENTITY = 'Managed Identity';

This requires the server to be connected to Azure Arc with managed identity enabled. For servers that reach Azure resources, it’s the cleanest way to stop managing secrets. In Azure SQL Database and Managed Instance, managed identity is available directly.

Production Checklist

  • Put API keys, SAS tokens and passwords in credentials, not in code, job steps or @headers.
  • Keep the master key password in your enterprise password vault and back up the key with BACKUP MASTER KEY.
  • Grant REFERENCES to roles, not individual users, and only on the credential that’s needed.
  • Generate SAS tokens with least privilege and an expiry date; use managed identity where possible.
  • Schedule secret rotation, track age with modify_date, and test right after each rotation.
  • Add the is_master_key_encrypted_by_server check to migration, upgrade and disaster recovery runbooks.
  • Plan master key access on Always On replicas before a failover happens.
  • Record credential creation and changes with SQL Server Audit.

For other server-level hardening steps, see our SQL Server security hardening checklist. How credentials connect SQL Server 2025 to embedding models is covered in vector search in Azure SQL.

Credential and Key Management with Aryasoft

Credential problems rarely show up on the day the credential is created. They appear months later, during a migration, a failover or a restore. If nobody knows the master key password at that moment, a configuration issue turns into a data access outage. In our security reviews Aryasoft looks at credentials, master keys, certificates and permissions together, documents where passwords and key backups are kept, and adds the necessary checks to migration and disaster recovery runbooks.

Frequently Asked Questions

No. The secret is encrypted with the master key and no catalog view or function shows it in plain text. sys.database_scoped_credentials shows only the name, identity and dates. If you’ve lost the secret, generate a new key in the source system and update the credential with ALTER.
Usually because the database was restored from another server or came online on a new replica after an Always On failover. The master key is still encrypted with the old server’s service master key. Fix it with OPEN MASTER KEY and ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY; don’t create a new master key.
No. BACKUP TO URL and RESTORE FROM URL use a server-level credential created with CREATE CREDENTIAL. Server credentials don’t travel with backups, so create them on every server.
No. External data sources reference the credential by ID. When you change the secret with ALTER DATABASE SCOPED CREDENTIAL, every dependent object uses the new value. Just remember to include both IDENTITY and SECRET in the statement.

Sources

The technical details in this guide were verified against the official documentation below in November 2026. Error messages and test results come from our SQL Server 2025 (17.0.4055.5) test server.

  1. Microsoft Learn: CREATE DATABASE SCOPED CREDENTIAL
  2. Microsoft Learn: ALTER DATABASE SCOPED CREDENTIAL
  3. Microsoft Learn: sp_control_dbmasterkey_password
  4. Microsoft Learn: CREATE MASTER KEY

SQL Server Consulting

No surprises on migration day

Aryasoft reviews your credentials, master keys and permissions and sets them up to keep working through restores, failovers and upgrades.

4.7/5