DEV Community

Derek Mwale
Derek Mwale

Posted on

What Happens When Security Becomes Part of the Data Model

Security is often introduced into software as a layer.

There is an application.

There is a database.

There is an API.

Then, somewhere around all of them, there is authentication, authorization, encryption, validation, logging, permissions, and a collection of rules that determine who can do what.

This mental model is useful.

But it has a limitation.

It makes security feel like something added to the system rather than something the system actually knows about.

A different approach begins with a simple idea:

What if security were part of the data model itself?

Instead of treating security as a collection of checks surrounding the data, we can represent important security properties directly within the structures that describe the data.

A record does not simply belong to a user.

It can explicitly belong to an organization.

A document does not simply exist.

It can carry an access classification.

A resource does not merely have an ID.

It can have an owner, a visibility level, a policy reference, or a set of relationships that determine who may interact with it.

At that point, security stops being only a gate around the database.

It becomes part of the architecture's vocabulary.

And that changes how we design systems.


Security Usually Starts Outside the Data

Consider a simple application with users and documents.

A conventional database might contain:

users
-----
id
name
email

documents
---------
id
title
content
user_id
created_at
Enter fullscreen mode Exit fullscreen mode

The relationship is straightforward.

A document belongs to a user.

Now imagine the application receives:

GET /documents/42
Enter fullscreen mode Exit fullscreen mode

The backend might retrieve document 42, inspect the authenticated user, and then determine whether that user is allowed to see it.

Conceptually:

request
   ↓
authenticate user
   ↓
find document
   ↓
check permission
   ↓
return document
Enter fullscreen mode Exit fullscreen mode

This works.

But notice where the security rule lives.

The database knows that the document belongs to a user.

The application knows that only certain users should access it.

The security rule exists primarily in application logic.

Now imagine a larger system.

There are administrators.

Teams.

Organizations.

Projects.

Guests.

Service accounts.

Temporary access.

Shared documents.

Private documents.

Archived documents.

Delegated permissions.

Suddenly, authorization logic can become distributed across many parts of the application.

The database describes the data.

The application describes the security.

The two models begin to drift apart.

This is where the idea of security-aware data modeling becomes interesting.


The Data Model Can Describe More Than Data

A database schema is often thought of as a description of what exists.

But a mature data model can describe relationships, ownership, boundaries, states, and constraints.

Security naturally fits into those categories.

Consider:

documents
---------
id
owner_id
organization_id
visibility
classification
status
created_at
Enter fullscreen mode Exit fullscreen mode

Now the document contains information that contributes directly to its security semantics.

For example:

visibility = private
Enter fullscreen mode Exit fullscreen mode

means something different from:

visibility = organization
Enter fullscreen mode Exit fullscreen mode

and:

visibility = public
Enter fullscreen mode Exit fullscreen mode

The system can reason about these values.

The important shift is subtle.

Instead of asking only:

Who owns this object?

we can ask:

What security properties are intrinsic to this object?

That question leads to richer models.


Ownership Is a Security Relationship

Ownership is one of the simplest examples.

Imagine a file:

File
 ├── id
 ├── name
 ├── owner_id
 └── created_at
Enter fullscreen mode Exit fullscreen mode

The owner_id field is not merely a business relationship.

It has security meaning.

It establishes a relationship between an identity and a resource.

That relationship can become the foundation for authorization.

For example:

User 17
   │
   ├── owns → File 82
   ├── owns → File 91
   └── owns → File 103
Enter fullscreen mode Exit fullscreen mode

Now consider a multi-tenant application.

The model might become:

organizations
-------------
id
name

users
-----
id
organization_id

documents
---------
id
organization_id
owner_id
Enter fullscreen mode Exit fullscreen mode

The organization relationship becomes another security boundary.

A query can therefore be designed around the tenant:

SELECT *
FROM documents
WHERE organization_id = ?;
Enter fullscreen mode Exit fullscreen mode

The data model itself makes the boundary visible.

This is powerful because security boundaries become structural rather than purely conceptual.


Security Can Become Relational

One of the most interesting consequences of security-aware modeling is that authorization can be represented as relationships.

Consider a project-management system.

A user can belong to a project.

users
projects
project_members
Enter fullscreen mode Exit fullscreen mode

The relationship table might contain:

project_members
---------------
project_id
user_id
role
Enter fullscreen mode Exit fullscreen mode

Now role becomes part of the security model.

For example:

user A → project X → owner
user B → project X → editor
user C → project X → viewer
Enter fullscreen mode Exit fullscreen mode

Security is no longer simply:

if user.is_admin:
    allow()
Enter fullscreen mode Exit fullscreen mode

It can become:

if membership.role permits action:
    allow()
Enter fullscreen mode Exit fullscreen mode

That difference matters.

The permission is attached to a relationship.

This makes authorization more expressive.

A user does not necessarily have one global permission level.

Their permission can depend on context.

They might be an editor in one project and a viewer in another.

The data model can represent that naturally.


Permissions Become Data

Once security enters the data model, permissions themselves can become records.

For example:

permissions
-----------
id
name
Enter fullscreen mode Exit fullscreen mode

With values such as:

documents.read
documents.write
documents.delete
projects.manage
users.invite
Enter fullscreen mode Exit fullscreen mode

Roles can then reference permissions.

roles
-----
id
name

role_permissions
----------------
role_id
permission_id
Enter fullscreen mode Exit fullscreen mode

Users or memberships can reference roles.

The architecture becomes something like:

User
  ↓
Membership
  ↓
Role
  ↓
Permissions
  ↓
Resource
Enter fullscreen mode Exit fullscreen mode

This creates a chain of meaning.

Instead of scattering authorization decisions throughout controllers, services, and routes, the system has a model that describes how permission is constructed.

The code still performs the final decision.

But the information required to make that decision exists in structured form.


Security Metadata Is Architectural Metadata

Another useful concept is security metadata.

A resource might carry information such as:

visibility
classification
owner
tenant
region
retention_policy
sensitivity
status
Enter fullscreen mode Exit fullscreen mode

Not every system needs all of these.

The point is that security-related properties can be represented explicitly.

Imagine an internal knowledge platform.

A document could look conceptually like:

{
  "id": 81,
  "title": "Engineering Handbook",
  "organization_id": 7,
  "visibility": "internal",
  "classification": "team",
  "owner_id": 42
}
Enter fullscreen mode Exit fullscreen mode

Now the document carries a security vocabulary.

An authorization layer can interpret those properties.

This can make the architecture easier to reason about because the security characteristics of an object are not hidden entirely inside application code.


State Can Also Be Security

Security is not always about identity.

Sometimes it is about state.

Consider a financial record.

A transaction might move through:

created
pending
approved
completed
cancelled
Enter fullscreen mode Exit fullscreen mode

The operations permitted at each state can differ.

For example:

pending → editable
approved → read-only
completed → immutable
Enter fullscreen mode Exit fullscreen mode

The state therefore influences the security model.

This is an important design observation:

Authorization can depend on both who you are and what the object currently is.

A user might normally be allowed to edit a transaction.

But once the transaction reaches a particular state, editing may no longer be appropriate.

The data model captures the state.

The security model interprets it.

The two become connected.


Security Boundaries Can Become Query Boundaries

One of the most practical benefits of security-aware modeling appears in database queries.

Suppose an application has ten million records.

A request comes from a user belonging to organization 42.

A poorly structured application might retrieve records broadly and then filter them afterward.

A security-aware architecture tries to make the boundary part of the query itself.

Instead of:

fetch everything
      ↓
filter unauthorized records
Enter fullscreen mode Exit fullscreen mode

the system aims for:

query only records inside the permitted boundary
Enter fullscreen mode Exit fullscreen mode

Conceptually:

SELECT *
FROM documents
WHERE organization_id = 42;
Enter fullscreen mode Exit fullscreen mode

The database becomes part of the enforcement path.

This does not mean the database should become responsible for every authorization decision.

It means the data model should make secure boundaries easy to express.

That is a valuable distinction.


The Principle of Secure Defaults

Once security becomes part of the data model, default values become important.

Consider:

visibility
Enter fullscreen mode Exit fullscreen mode

What should a newly created document be?

Public?

Private?

Organization-only?

If the default is ambiguous, security becomes dependent on every caller remembering to specify the correct value.

A better model gives the field an explicit safe default.

Conceptually:

visibility = private
Enter fullscreen mode Exit fullscreen mode

Then the application must deliberately choose a broader visibility level.

This produces a useful architectural principle:

The easiest state to create should also be a well-defined security state.

Good data models reduce the number of accidental states that can exist.


Security Constraints Can Protect Invariants

Data integrity and security often overlap.

Suppose every document must belong to an organization.

Then:

organization_id
Enter fullscreen mode Exit fullscreen mode

should not casually be nullable.

If a document can exist without an organization, the security model now has to answer:

Who owns this document?

The absence of a security relationship can become an architectural problem.

Constraints can therefore help preserve security assumptions.

Examples include:

  • foreign keys,
  • non-null ownership fields,
  • unique membership constraints,
  • controlled enumerations,
  • database policies,
  • immutable audit identifiers.

The more accurately the database represents the system's invariants, the fewer ambiguous states the application has to handle.


Auditability Becomes Part of the Model

Security is not only about preventing actions.

It is also about understanding actions.

Consider an audit table:

audit_events
------------
id
actor_id
action
resource_type
resource_id
timestamp
metadata
Enter fullscreen mode Exit fullscreen mode

Now the system can represent events such as:

User 42
updated
Document 81
at 10:32
Enter fullscreen mode Exit fullscreen mode

This creates a historical dimension to the data model.

The system does not only know:

What exists?

It can also know:

What happened?

That distinction becomes extremely useful in systems where accountability and traceability matter.

Auditability turns security from a purely preventative mechanism into something that also supports observation and investigation.


Security as a Graph

At larger scales, security can be understood as a graph.

Imagine:

User
 │
 ├── belongs to → Organization
 │
 ├── member of → Project
 │                  │
 │                  └── contains → Document
 │
 └── assigned → Role
                    │
                    └── grants → Permission
Enter fullscreen mode Exit fullscreen mode

The authorization question becomes a graph traversal problem.

For example:

Can User A
    access
Document B?
Enter fullscreen mode Exit fullscreen mode

The answer may depend on a chain:

User A
  ↓
Membership
  ↓
Project
  ↓
Document B
Enter fullscreen mode Exit fullscreen mode

Or:

User A
  ↓
Role
  ↓
Permission
  ↓
Document B
Enter fullscreen mode Exit fullscreen mode

This is one reason relationship-oriented authorization models can become powerful.

They describe security as connections rather than isolated flags.


The Data Model Becomes a Security Map

A well-designed schema can almost become a map of the application's trust boundaries.

You can look at the tables and ask:

Who owns this?

Who can access this?

Which organization contains this?

Which relationship grants access?

What state is this resource in?

What events have happened to it?
Enter fullscreen mode Exit fullscreen mode

If the answers are represented clearly in the model, the architecture becomes easier to understand.

This has another benefit.

New developers can inspect the schema and discover important security relationships without reading every controller.

The data model becomes documentation.

Not complete documentation.

But meaningful architectural documentation.


This Does Not Mean Putting Every Security Rule in the Database

There is an important balance here.

Making security part of the data model does not mean putting every authorization decision into SQL.

Applications still need:

  • authentication,
  • authorization services,
  • policy evaluation,
  • input validation,
  • session management,
  • encryption,
  • secure communication,
  • rate limiting,
  • monitoring,
  • logging,
  • operational controls.

The database is one component of a larger security architecture.

The deeper idea is simply that security should not be completely disconnected from the representation of data.

A resource's ownership, tenant, state, classification, and relationships are often fundamental properties of that resource.

Representing them explicitly gives the rest of the system something concrete to reason about.


Security-Aware APIs

This philosophy also changes API design.

Consider an endpoint:

GET /documents/81
Enter fullscreen mode Exit fullscreen mode

The endpoint does not merely need to know that document 81 exists.

It needs to establish whether the current request context permits access.

A useful architecture can represent the request context as:

identity
tenant
roles
permissions
relationships
resource
resource state
Enter fullscreen mode Exit fullscreen mode

The authorization decision becomes a function of these inputs.

Conceptually:

authorize(
    identity,
    action,
    resource,
    context
)
Enter fullscreen mode Exit fullscreen mode

The resource itself provides part of the information.

This makes authorization easier to reason about than a collection of unrelated boolean checks.


Security and Domain Modeling Start to Meet

There is a larger architectural lesson here.

Security is often treated as infrastructure.

Domain modeling is treated as application design.

But they frequently overlap.

Imagine an educational platform.

The domain contains:

Student
Teacher
Course
Assignment
Submission
Grade
Enter fullscreen mode Exit fullscreen mode

Security relationships naturally emerge:

Teacher → owns → Course
Student → enrolled in → Course
Student → creates → Submission
Teacher → evaluates → Submission
Enter fullscreen mode Exit fullscreen mode

These are domain relationships.

They are also security relationships.

The architecture does not need to invent them separately.

The same model can describe both business meaning and access boundaries.

That is one of the most elegant aspects of security-aware design.


When Security Becomes Visible, Architecture Improves

Hidden rules are difficult to maintain.

If security exists only as scattered conditional statements, it can become difficult to understand the complete security model.

But when important security relationships become explicit:

owner_id
organization_id
role_id
visibility
classification
status
membership
audit_event
Enter fullscreen mode Exit fullscreen mode

the architecture becomes more observable.

You can inspect the model.

You can diagram it.

You can test it.

You can validate it.

You can reason about it.

Security becomes something engineers can see.

And things that can be clearly represented are usually easier to reason about.


Testing Becomes More Interesting

Security-aware data models also create opportunities for systematic testing.

Instead of testing only individual endpoints, engineers can test invariants.

For example:

A user cannot access resources outside their organization.

A viewer cannot perform editor operations.

An archived resource cannot be modified.

A deleted membership cannot grant access.

A private resource cannot become public without an explicit transition.
Enter fullscreen mode Exit fullscreen mode

These become properties of the system.

Tests can then operate at multiple levels:

data constraints
      ↓
domain rules
      ↓
authorization policies
      ↓
API behavior
Enter fullscreen mode Exit fullscreen mode

The security model becomes testable as architecture rather than only as isolated endpoint behavior.


The Future of Security May Look More Like Modeling

As applications become more interconnected, simple permission checks become less representative of reality.

Modern systems contain:

users
organizations
teams
devices
services
documents
projects
workflows
events
resources
policies
Enter fullscreen mode Exit fullscreen mode

The relationships between them matter.

Security increasingly becomes a question of context.

Who is making the request?

What are they trying to access?

What relationship do they have with it?

Which organization does it belong to?

What state is it in?

What policies apply?

What happened previously?

Those questions sound less like a firewall configuration and more like data modeling.

Perhaps that is the deeper shift.

Security is not merely about building walls around information.

It is also about accurately describing the relationships that determine how information should move through a system.


The Architecture Starts With Meaning

The strongest systems often begin with good representations.

A user is not merely an integer.

A document is not merely a row.

A project is not merely a table.

A relationship is not merely a foreign key.

Each represents something meaningful.

Once security becomes part of the data model, those meanings become richer.

A document has an owner.

A resource belongs to a boundary.

A user has a relationship with an organization.

A role grants capabilities.

A state changes what operations make sense.

An event records what happened.

These are not just database details.

They are architectural facts.

And architectural facts are valuable when they are explicit.


Final Thoughts

Security can be treated as a layer surrounding an application.

But it can also be treated as part of the application's vocabulary.

That second perspective leads to an interesting design principle:

If a security property fundamentally describes a resource or relationship, consider representing it in the model.

Ownership can be data.

Tenant boundaries can be data.

Visibility can be data.

Roles can be data.

Permissions can be data.

Security-relevant state can be data.

Audit history can be data.

The goal is not to turn the database into a security engine.

The goal is to make important security assumptions visible, structured, and testable.

When security becomes part of the data model, the architecture starts telling a more complete story.

It no longer says only:

Here is the information our system stores.

It begins to say:

Here is what exists, who it belongs to, how it is connected, what state it is in, and which relationships give it meaning.

That is a much richer model of a system.

And perhaps the most useful security boundary is not always the one we draw around the data.

Sometimes it is the one we encode inside the data itself.

Software in My Mind. Rock in My Soul.

Top comments (0)