Skip to main content

Client API Key Lite: Service to Service Design

A lightweight Client API Key design for service-to-service communication using a 6-column database table and 10 lines of code.

AI-written
Inewgen
29 Aug 2026Source: Dev.to3 min read (0 views)
Share
Client API Key Lite: Service to Service Design

Stock photo for illustration only, not from the actual event

Font size
  • Design API keys for service-to-service communication using a 6-column table and 10 lines of code
  • Store SHA-256 hashes instead of plain text to prevent risks during database leaks
  • Use revoked_at instead of a UNIQUE constraint on the consumer to support zero-downtime key rotation
  • Separate the resolver from framework middleware for better code maintainability

When another team requests integration with your service, identifying the caller accurately is paramount. Common approaches usually lean towards two extremes: storing a random UUID or hash in an environment variable until it leaks, or bringing in the entire OAuth2 suite which introduces unnecessary complexity. This post explores the middle ground.

This design focuses strictly on service-to-service communication, excluding user-generated keys created from web interfaces. Three foundational assumptions enable this lightweight approach. If dealing with a public API, these assumptions break down, requiring rate limiting, a key management dashboard, expiration dates, and granular permission scopes.

software developer workspace notebook computer office desk workspace

Stock photo for illustration only, not from the actual event

Early-stage security architecture often forces a trade-off between simplicity and complexity. Adopting a light design reduces initial engineering overhead while requiring a robust database foundation to prevent costly technical debt later.

The 6-column database table structure consists of:

  • id INT AUTO_INCREMENT PRIMARY KEY
  • consumer VARCHAR(100) NOT NULL (do not add UNIQUE)
  • key_hash CHAR(64) NOT NULL UNIQUE (SHA-256 hex of the full key)
  • revoked_at DATETIME NULL
  • description VARCHAR(255) (ticket number and requester)
  • created_at and updated_at timestamps
6Database Columns
64SHA-256 Hex Chars

The first critical decision is avoiding plain-text key storage to eliminate risks from database dumps lingering on developer machines. Storing the SHA-256(key) and querying the hash directly eliminates the need for Bcrypt, as a 256-bit random value leaves nothing to guess.

Never miss the latest news?

Subscribe to get news summaries by email - not often enough to be annoying.

โฆษณา

Another vital practice is utilizing a revoked_at timestamp column paired with an explicit AND revoked_at IS NULL condition directly inside the SQL query, avoiding application-layer filtering to prevent future oversights.

"สิ่งที่ UNIQUE ตรงนี้แปลว่า คุณหมุน key (key rotation) ไม่ได้ เพราะ key rotation ที่ปลอดภัยต้องมีช่วงที่ key เก่ากับใหม่ใช้ได้พร้อมกัน"

Dev.to Author

Omitting the UNIQUE constraint on the consumer column enables seamless key rotation with zero downtime. The process involves inserting a new key, switching the consumer over, verifying that zero traffic remains on the old key, and subsequently revoking the old key.

When generating keys, command syntax matters—using printf instead of echo prevents unwanted trailing newlines that alter hash values. Furthermore, deliver credentials securely via the consumer's secret manager rather than standard chat or email channels.

Source: Dev.to

Comments

Leave a Comment
0/2000

Found something wrong in this article? Report an issue with this article