As Zingage rapidly expanded to hundreds of customers nationwide, our engineering team faced increasingly complex technical challenges: robust data isolation, seamless scaling, and high availability during intensive operations. Standard UUIDs quickly proved insufficient, exposing several critical issues:
- Data Leakage Risk: Forgetting to filter queries by
businessId
could expose sensitive data across businesses. - Complex Partitioning: Lack of inherent business context made data partitioning challenging and inefficient.
- Ambiguous Entity Scope: Without clear entity boundaries, managing data across multiple tenants became error-prone.
The Limitations of Traditional UUIDs
Consider this problematic scenario:
const profileId = uuidv4();
// Risky query (business context omitted)
const profile = await db.profiles.findOne({ id: profileId });
// Potentially exposes data from another business inadvertently
This approach, although common, risks critical data leaks in multi-tenant environments.
Introducing Zingage IDs: A Robust Multi-Tenant Solution
To address these challenges, we designed a structured UUIDv8-based identifier system, embedding clear business context and distinct entity scopes directly within the IDs:
- Business IDs (
000
prefix): Represent unique business entities. - Business-scoped Entity IDs (
1
prefix): Clearly tied to specific businesses, embedding business identifiers. - Cross-business Entity IDs (
001
prefix): Explicitly defined to represent resources shared across businesses.
Code Example
Here's how this looks in practice:
import { generateBusinessId, generateScopedId } from 'zingage-id';
const businessId = generateBusinessId();
const profileId = generateScopedId(businessId, 'PROFILE');
// Secure query with embedded business context
const profile = await db.profiles.findOne({ id: profileId });
// Built-in safeguards ensure correct business scope, preventing leaks
Advanced Collision Resistance and Debugging Capabilities
Zingage IDs leverage structured components—42-bit timestamps, 10-bit entity type hints, and opaque random data—to provide strong collision resistance and powerful debugging:
- Collision Resistance: By combining precise timestamps with robust random bits, we drastically lower collision risks, even under high-load scenarios. For example, generating up to 100,000 IDs per day produces only a minimal annual collision probability (~7% under highly conservative assumptions).
- Debugging Efficiency: Entity type hints embedded within IDs enable rapid issue identification during debugging, without imposing rigid constraints. This ensures flexibility for future entity restructuring or data migration tasks.
Built-In Database-Level Security Enforcement
Our ID scheme integrates seamlessly with database-level Row-Level Security (RLS) policies, providing automatic, foolproof data isolation:
-- Enforce strict business context at the database level
CREATE POLICY business_scope_policy ON profiles
USING (extract_business_id(id) = current_setting('app.current_business_id')::uuid);
With this policy, database queries automatically apply business scoping, significantly reducing the risk of accidental data exposure.
Middleware further enhances security by automatically setting business context on a request level.
// Middleware example
app.use((req, res, next) => {
const businessId = extractBusinessIdFromRequest(req);
db.setBusinessContext(businessId);
next();
});
// Database query implicitly scoped
const profile = await db.profiles.findOne({ id: profileId });
// Automatically executes as:
// SELECT * FROM profiles WHERE id = :profileId AND business_id = :activeBusinessId
Simplified and Efficient Data Partitioning
Explicitly embedding business identifiers simplifies data partitioning dramatically:
- Business-scoped Entities: Directly embed business IDs, enabling straightforward partitioning and isolation per business.
- Cross-business Entities: Clearly separated and replicated across partitions to ensure consistency and accessibility.
Practical partitioning example:
CREATE TABLE profiles (
id UUID PRIMARY KEY,
...
) PARTITION BY HASH (business_id_embedded_in_uuid);
CREATE TABLE workflow_templates (
id UUID PRIMARY KEY,
...
) -- Replicated across partitions due to cross-business applicability
This explicit delineation dramatically enhances scalability, performance, and operational efficiency.
Key Benefits of the Zingage ID Scheme
- Robust Security: Intrinsic business isolation prevents accidental cross-tenant data breaches.
- Scalable Architecture: Simplified, efficient partitioning supports effortless horizontal scaling.
- Improved Developer Experience: Reduced manual context management and minimized risk of oversight.