SQL Azure DB – Creating a Restricted User in Azure SQL Who Owns Only Their Schema

Security in Azure SQL Database often starts with the principle of least privilege: a user should have access only to what they need, nothing more. A common pattern is to create a contained database user who can log in directly to a database, own a private schema, and have full control only inside it — creating, altering, and dropping objects freely, while remaining blind to everything else.

Why Use Schema-Level Isolation?

In shared databases, different applications or departments sometimes need to store their own data without touching each other’s structures. Granting everyone broad permissions like db_datareader or db_datawriter is easy but unsafe. Schema-level isolation gives each user their own sandbox while maintaining a single database for administration and cost efficiency.

Step 1 – Create the Contained User

Azure SQL uses contained users, meaning their authentication lives inside the database itself — no server-level login is required. Connect as a privileged user (for example, db_owner) and run:

--Run script inside your database (NOT in Master DB)

CREATE USER [cda] WITH PASSWORD = MyPassword123';

This creates a self-contained SQL user named cda that can authenticate directly to your target database.

Step 2 – Create and Assign the Schema

Now create a schema with the same name and assign ownership to that user:

CREATE SCHEMA [cda] AUTHORIZATION [cda];
ALTER USER [cda] WITH DEFAULT_SCHEMA = [cda];

By owning the schema, the user automatically gains control over all objects inside it.

Step 3 – Grant Database-Level Create Permissions

Schema ownership alone isn’t enough to create new tables; Azure SQL still requires a database-level permission:

GRANT CREATE TABLE TO [cda];

his allows table creation — but since cda doesn’t control any other schema, the user can create objects only within their own.

Step 4 – (Optional) Allow SSMS Login Through Master

If you want the user to log in through SQL Server Management Studio (SSMS) without specifying a database in the connection string, you can mirror the user in the master database:

--Run script inside Master DB

CREATE USER [cda] WITH PASSWORD = 'MyPassword123';

This adds a harmless “parking user” in master, with no permissions, letting SSMS connect successfully before switching context to your target db.

Step 5 – Test the Setup

Log in as cda and run:

CREATE TABLE cda.test_table (
    id INT IDENTITY(1,1) PRIMARY KEY,
    note NVARCHAR(100),
    created_at DATETIME2 DEFAULT SYSDATETIME()
);

INSERT INTO cda.test_table (note) VALUES (N'Test successful!');
SELECT * FROM cda.test_table;

If it runs, the configuration works — the user can manage everything within cda and nothing outside it.

Why This Matters

This design achieves strong isolation without creating multiple databases or complex roles. Each user has:

  • Direct access via contained login
  • Exclusive ownership of their schema
  • Full DDL/DML freedom within it
  • No visibility into other data

In short, a perfect balance between autonomy and control — ideal for multi-tenant solutions, departmental data marts, or any environment where you want to empower users without jeopardizing security.

Leave a comment