Menu
Medium #system-design·March 13, 2026

API Design: Protecting Database IDs with Public Identifiers

This article discusses a critical API design best practice: avoiding the direct exposure of internal database primary keys (IDs) to clients. It advocates for using separate, public-facing identifiers to enhance security, improve system flexibility, and prevent data leakage, which are important considerations in system architecture.

Read original on Medium #system-design

The Problem with Exposing Database IDs

Exposing internal database IDs directly in APIs can lead to several security and architectural vulnerabilities. These IDs often reveal implementation details, such as the total number of records, and can be used to infer system growth or enumerate resources. This can make systems more susceptible to scraping, data exploration, and potentially even denial-of-service attacks if IDs are guessable (e.g., sequential integers). From a system design perspective, tying the public API directly to internal database schema creates tight coupling, making future schema changes more difficult without breaking client applications.

Security Implications

  • Enumeration Attacks: Attackers can iterate through sequential IDs to discover other users or resources.
  • Information Leakage: Sequential IDs can reveal the total count of records, system activity, and growth patterns.
  • Predictability: Guessable IDs make it easier for malicious actors to craft requests to access unauthorized data.

Introducing Public Identifiers

To mitigate these risks, the recommended approach is to use public identifiers (Public IDs) that are distinct from internal database primary keys. These Public IDs should be opaque, non-sequential, and difficult to guess. UUIDs (Universally Unique Identifiers) are a common and effective choice for Public IDs, offering global uniqueness and randomness. Implementing Public IDs creates a crucial abstraction layer between the external API contract and the internal data storage mechanism.

Architectural Benefits

  • Decoupling: Enables independent evolution of database schemas and API contracts.
  • Security by Obscurity (Partial): While not a primary security measure, it adds a layer of difficulty for attackers. Always combine with proper authorization.
  • Flexibility: Allows changes to the underlying database (e.g., sharding, database migration) without impacting API clients.
  • Multi-tenancy: Easier to implement secure multi-tenant systems where tenants cannot guess IDs of other tenants' resources.
💡

Implementation Considerations

When implementing Public IDs, ensure they are indexed in the database for efficient lookups. Consider the trade-off between UUID v1 (time-based, potentially guessable parts) and UUID v4 (random) or ULIDs (Universally Unique Lexicographically Sortable Identifiers) which offer uniqueness and time-sortability, beneficial for indexing.

APIsecuritydatabaseidentifierUUIDsystem design fundamentalsdata exposureAPI best practices

Comments

Loading comments...