Skip to main content

API property-level authorization: prevent data exposure and mass assignment

Control which SaaS API fields each role can read or change with explicit response and request allowlists, safe update models, and tests for excessive data exposure and mass assignment.

In this guide

What is API property-level authorization, and how do you enforce it?

Object-level authorization answers whether a person may access a record; property-level authorization answers which fields on that record they may see or change. Build each API response from an explicit set of fields the caller needs, and accept updates through an explicit set of fields that caller may edit. Do not serialize an entire database model or bind an arbitrary request body to it. This reduces excessive data exposure and mass-assignment risk, even when the caller may legitimately access the object.

Return only fields needed for this audience and operation

Use response DTOs, resource serializers or schema definitions that deliberately select public fields for each endpoint and role. A customer viewing their own account may need their display name and plan, but not internal risk notes, authentication factors, billing-provider secrets or moderation flags. Treat nested GraphQL and REST objects the same way, and review fields added during model changes.

Allow updates through a purpose-built field list

Map request input into a command or update object containing only fields that this action is meant to change. Do not mass-assign raw JSON into an ORM model, user object or administrative record. Derive values such as tenant, account status, billing state, role, verification state and ownership on the server rather than accepting them from a customer request.

API property-access matrix worksheet
Endpoint and roleObject fields returnedFields accepted for updateServer-derived fields to rejectRead/write tests and owner
Profile: member
Billing: workspace owner
Moderation: support operator

Which design choices prevent accidental field exposure?

Keep public response schemas separate from persistence models

Database models often contain fields intended only for internal workflows. Define an API response shape that selects the minimum required values, then validate it before returning sensitive endpoints where practical. Avoid generic toJSON or automatic model serialization as the default contract, especially when the model gains new columns over time.

Use explicit input validation for create, patch and bulk actions

A validation rule that accepts any known model property can still expose fields the current caller should not control. Define field allowlists per operation, role and API version; reject unexpected fields or handle them consistently without silently applying them. Repeat the same check for imports, GraphQL mutations, background jobs and bulk endpoints.

Treat hidden, derived and workflow fields as sensitive

Fields such as `isAdmin`, `verified`, `approved`, `blocked`, `price`, `creditLimit`, `tenantId` and `ownerId` can change access or money movement. Compute or update them through dedicated server-side workflows with their own authorization, validation and audit trail. Do not accept them merely because a database column exists.

How do you test for property-level access flaws?

Test both excess reads and unauthorized writes

For each role and object type, compare returned fields with the approved response schema. Then submit extra fields on create, patch, nested update and bulk operations and confirm protected values do not change. Include a user who owns the object but is still not allowed to view or alter every property.

Use role, tenant and workflow-state combinations

Test a member, owner, support operator and any limited or suspended account across records in separate tenants. Check fields before and after approval, payment, verification or moderation transitions. Confirm API errors do not leak the rejected secret value and no partial changes are committed.

Add regression checks to schema and model changes

When a field is added to a data model, API serializer or GraphQL type, ask whether it is meant to be public, readable by each role and writable through each operation. Keep tests tied to explicit field lists so a new column cannot silently become part of a public response. Review API versions and generated clients after schema changes.

API property-authorization questions