24. Database Authorization¶
A perfectly normalized, perfectly indexed database is worthless if the wrong person can
read the salary table or delete the enrollment records. Authorization is the layer that
decides, for every user and every operation, whether it's allowed — and SQL has a compact,
standard vocabulary for expressing exactly that: GRANT, REVOKE, and roles. This lecture
covers that vocabulary end to end, and closes the loop with Lecture 23 by showing how a view
becomes, in practice, one of the most common and effective security tools a database
designer has.
In This Lecture¶
- Why database security matters: confidentiality, integrity, and availability
- Database users and privileges
- Discretionary vs. mandatory access control, briefly
- Granting privileges with
GRANT ... ON ... TO ... - Revoking privileges with
REVOKE - Roles and role-based access control — why they beat granting to individuals directly
- Authorization rules and how the DBMS enforces them
- Views as a security mechanism, tying directly back to Lecture 23
- A consolidated reference of SQL authorization commands
- Security considerations: SQL injection and the least-privilege principle
Database Security and Authorization¶
Database security is the protection of data against unauthorized access, modification, or destruction. It rests on three classic goals, usually called the CIA triad:
- Confidentiality — only authorized users can read the data (a student shouldn't read other students' grades).
- Integrity — only authorized users can modify the data, and only in permitted ways (a student shouldn't be able to edit their own grade).
- Availability — authorized users can access the data when they need it; security controls should not themselves become the reason legitimate access fails.
Authorization is the specific mechanism that decides who may do what to which data — it answers "is this particular operation, by this particular user, on this particular object, allowed right now?" It is distinct from authentication (proving who you are, e.g. logging in with a password) — authentication happens first, authorization happens on every subsequent operation.
Database Users and Privileges¶
Every operation in a DBMS happens under some user (or role) identity, and every user holds a set of privileges — specific permissions to perform specific operations on specific database objects. The common privilege types map directly onto SQL's data operations:
Common SQL Privileges
SELECTRead rows from a table or view
INSERTAdd new rows
UPDATEModify existing rows
DELETERemove rows
EXECUTERun a stored procedure or function
ALL PRIVILEGESShorthand for every applicable privilege at once
Access Control: Discretionary vs. Mandatory¶
Two broad models govern how privileges get assigned:
- Discretionary Access Control (DAC) — the owner of an object (or an administrator)
decides, at their discretion, who gets which privileges on it. This is what
GRANTandREVOKEimplement, and what almost every relational DBMS uses by default. - Mandatory Access Control (MAC) — every object and every user carries a fixed
security classification (e.g.
unclassified,secret,top secret), and access is decided by comparing classifications according to a system-wide policy that individual users cannot override, even if they own the object. MAC appears mainly in government and military-grade systems; this course focuses on DAC, since it's what you'll actually use in a standard SQL database.
Granting Privileges¶
GRANT gives one or more privileges, on one object, to one or more users (or roles):
Column-level granularity restricts a privilege to specific columns only — useful when a user needs to update some fields but never others:
EXECUTE applies to stored procedures and functions rather than tables:
WITH GRANT OPTION additionally lets the recipient grant the same privilege on to others
— without it, a user can use the privilege but cannot pass it along:
GRANT OPTION spreads responsibility, not just access
Once branch_manager holds SELECT ... WITH GRANT OPTION, they can run
GRANT SELECT ON Staff TO some_other_user themselves, without the database
administrator's involvement. This is powerful for delegating administration, but it also
means privilege chains can grow past what a single audit of GRANT statements at the
top makes obvious — a real reason to use WITH GRANT OPTION sparingly.
Revoking Privileges¶
REVOKE removes a previously granted privilege — the mirror image of GRANT, with matching
syntax:
Revoking a privilege that was granted WITH GRANT OPTION typically cascades: privileges
that were granted onward because of that option are revoked too, unless the system
provides an explicit RESTRICT to block a revoke that would cascade:
Roles and Role-Based Access Control¶
Granting privileges directly to dozens or hundreds of individual users does not scale — every
new hire needs the same ten GRANT statements typed out again, and every policy change means
re-running them against every affected user individually. Role-Based Access Control
(RBAC) fixes this by inserting one extra layer: define a role as a named bundle of
privileges, then assign users to roles instead of granting to users directly.
Role-Based Access Control
1. CREATE ROLEDefine a named role, e.g. branch_staff
2. GRANT privileges TO the roleBundle every privilege the role needs, once
3. GRANT the role TO usersEvery user assigned the role inherits the whole bundle immediately
CREATE ROLE branch_staff;
GRANT SELECT, INSERT, UPDATE ON Staff TO branch_staff;
GRANT SELECT ON Branch TO branch_staff;
GRANT branch_staff TO usman, ayesha, hamza;
When policy changes, you change it once, on the role — every assigned user picks up the
new privilege set immediately, with no per-user GRANT statements to hunt down and re-run:
GRANT DELETE ON Staff TO branch_staff; -- every user with this role now has DELETE too
REVOKE branch_staff FROM hamza; -- hamza loses the entire bundle in one statement
Roles vs. individual grants, in one sentence
Grant privileges to roles, and assign users to roles — never the other way around, unless a privilege is genuinely unique to one specific person and will never apply to a second user.
Authorization Rules¶
An authorization rule is the DBMS's internal record of exactly which privilege a
specific user (or role) holds on a specific object — effectively a row in the DBMS's own
system catalog, of the rough shape (grantor, grantee, object, privilege, grantable?). Every
time a user issues a SQL statement, the DBMS's authorization subsystem checks the statement
against these rules before executing anything: no matching rule means the statement is
rejected outright, regardless of whether the underlying operation would otherwise succeed.
This check happens on every single statement, every single time — authorization is not a
one-time login check, it's continuously enforced.
Views for Security¶
Lecture 23 introduced views as a way to present a convenient shape over a normalized schema. That same mechanism is one of the most practical security tools available, because a view can restrict which rows and columns a user ever sees — privileges are then granted on the view, not on the underlying table, so the restriction is structural, not just a matter of application-level discipline.
Restricting columns — hide salary from anyone who isn't HR:
CREATE VIEW StaffPublicInfo AS
SELECT staffNo, name, position, branchNo
FROM Staff;
GRANT SELECT ON StaffPublicInfo TO general_staff;
-- general_staff never gets SELECT on Staff itself, so salary stays invisible
Restricting rows — let each branch manager see only their own branch's staff:
CREATE VIEW MyBranchStaff AS
SELECT staffNo, name, position, salary
FROM Staff
WHERE branchNo = CURRENT_BRANCH(); -- resolved per session/user in a real system
GRANT SELECT ON MyBranchStaff TO branch_manager;
Because the branch manager is never granted any privilege on Staff directly, there is no
way for them to bypass the WHERE branchNo = ... filter by querying the base table instead
— the restriction holds regardless of what tool or client they use to connect.
This is exactly Lecture 23's updatability trade-off, revisited
StaffPublicInfo above is a single-table, no-aggregate view, so it remains updatable
under Lecture 23's rules — general_staff could plausibly be granted UPDATE on it for
the columns it exposes. A security view built on a join or aggregate, by contrast,
inherits the same non-updatability discussed last lecture — which is often exactly
what you want for a read-only reporting role.
SQL Authorization Commands — Consolidated Reference¶
| Command | Purpose |
|---|---|
GRANT <privileges> ON <object> TO <user\|role> |
Give one or more privileges on an object |
GRANT <privileges> ON <object> TO <user> WITH GRANT OPTION |
Give privileges, and permission to re-grant them |
REVOKE <privileges> ON <object> FROM <user\|role> |
Remove previously granted privileges |
REVOKE ... CASCADE |
Remove privileges, and cascade the revoke to anything granted onward because of them |
CREATE ROLE <name> |
Define a new named role |
GRANT <role> TO <user> |
Assign a user to a role, inheriting its whole privilege bundle |
REVOKE <role> FROM <user> |
Remove a user from a role |
CREATE VIEW ... AS SELECT ... |
Define a restricted row/column subset to grant privileges on instead of a base table |
Security Considerations¶
SQL Injection: the single most common real-world database attack
SQL injection occurs when untrusted input (typically from a web form) is concatenated directly into a SQL string instead of being passed as a properly separated parameter, letting an attacker inject their own SQL logic:
-- Application builds this string directly from user input:
"SELECT * FROM Staff WHERE staffNo = '" + userInput + "'"
-- Attacker submits, as userInput:
' OR '1'='1
-- Resulting statement actually executed:
SELECT * FROM Staff WHERE staffNo = '' OR '1'='1'
-- returns EVERY row, bypassing the intended filter entirely
'; DROP TABLE Staff; --) if the
driver allows multiple statements per call. The fix is parameterized queries /
prepared statements, never string concatenation:
Authorization and parameterized queries are complementary, not substitutes for each
other: even a perfectly parameterized application still needs the user account it
connects as to hold only the minimum privileges it actually needs — the next point.
Least privilege is the governing principle behind everything in this lecture: grant a
user (or an application's own database account) exactly the privileges its job requires, and
nothing more. A reporting dashboard's database account needs SELECT and nothing else — it
should never hold DELETE on any table, precisely so that a bug or a successful injection
attack against that dashboard cannot destroy data it was never supposed to be able to touch
in the first place. Combined with roles (grant the role least privilege, once) and
security views (expose only the rows/columns a role actually needs), least privilege turns
authorization from a single login check into a system-wide, continuously-enforced discipline.
Try It Yourself¶
- Write the
CREATE ROLE,GRANT, and role-assignment statements to create aread_only_auditorrole that canSELECTfromStaffandBranchbut nothing else, and assign a user namedauditor1to it. - A junior developer proposes building a customer-facing search feature by concatenating
the search box's text directly into a SQL
WHEREclause string. Explain, in two or three sentences, exactly what could go wrong and what you'd tell them to do instead. - Design a security view (using Lecture 23's
CREATE VIEWsyntax) that lets apayroll_hrrole see every column ofStaff, but lets ageneral_staffrole see onlystaffNo,name, andposition— then write the two correspondingGRANT SELECTstatements.
Key Takeaways¶
- Authorization continuously decides who may do what to which data, resting on the CIA triad — confidentiality, integrity, and availability.
- SQL implements discretionary access control:
GRANTassigns privileges (SELECT,INSERT,UPDATE,DELETE,EXECUTE),REVOKEremoves them, andWITH GRANT OPTIONlets a recipient re-grant further. - Roles bundle privileges once and let you assign/revoke an entire policy for a user in a single statement — grant to roles, assign users to roles, essentially always.
- Views, introduced in Lecture 23 for convenience, double as a genuine security mechanism: grant privileges on a restricted view instead of the base table to enforce row- and column-level restrictions structurally, not just by application convention.
- SQL injection remains one of the most common real-world attacks against databases; parameterized queries prevent it, and the least-privilege principle limits the damage even when some other defense fails.
This closes Unit 6. Lecture 23's views
(Lecture 23, Views and Materialized Views) and
this lecture's GRANT/REVOKE/role vocabulary are the two tools you'll reach for most often
when a real deployed schema needs to serve multiple applications and user classes safely from
one underlying, fully normalized database.