Enterprise edition
SaaS
At a glance
Section titled “At a glance”NextPDF Enterprise provides the building blocks for a multi-tenant SaaS deployment: an immutable tenant context, scoped API keys with checksum and timing-safe verification, a pre-request quota check with 80%/100% behavior, and a pull-based metering sync to an external billing provider. This page describes the observable behavior and the public contract.
Availability & licensing
Section titled “Availability & licensing”This capability ships in NextPDF Enterprise (nextpdf/enterprise) and activates with an Enterprise-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.
The SaaS multi-tenancy surface is a base Enterprise capability, available once the package is installed; there is no separate per-feature flag.
Conceptual overview
Section titled “Conceptual overview”A tenant is represented by an immutable tenant context: a tenant identifier, the source that resolved it (a token, mutual-TLS, or an API key), and a set of authorized scopes. Tenant identity is always resolved from authenticated context — never from a client-supplied header or query parameter. A single-tenant deployment uses a fixed default context with full scopes.
API keys carry a human-readable prefix that distinguishes production from sandbox, a high-entropy random body, and a short checksum. The checksum is a fast typo-rejection convenience, not a security mechanism — it lets a malformed key be rejected before any datastore lookup. Authentication validates the checksum, hashes the key with SHA-256, looks the hash up in a repository, and rejects keys that are unknown, revoked, or expired. Keys are never logged or stored in clear text, and the stored value is the hash. Scope enforcement is explicit: a context can be required to hold a given scope.
The quota checker runs before a request proceeds. It reads the tenant’s current-period usage, warns at the soft limit (80%) through a caller-supplied alert callback, and rejects at the hard limit (100%) with a quota-exceeded condition that carries the reset instant. The period reset is the next month boundary in UTC.
The metering-sync adapter pulls usage events from the deployment’s authoritative usage source, transforms them into the billing provider’s meter-event shape with a stable idempotency key, and sends them. Failed events are routed to a dead-letter callback, and the syncer tracks a per-source cursor so a sync cycle resumes where the last one stopped. The billing provider integration is an interface, so the provider is swappable.
Why it works this way
Section titled “Why it works this way”The load-bearing decision is that NextPDF ships enforcement primitives, not a hosted platform. The TenantContext, ApiKeyAuthenticator, QuotaChecker, and metering-sync adapter are contracts your deployment wires to its own stores. Tenant identity resolves only from authenticated context, so a client can never assert its own tenant through a header. Keys live in your repository as SHA-256 hashes, quota reads your usage source, and the billing provider is a swappable interface. NextPDF persists nothing, so tenant data, keys, and billing stay under your control. Because the surface resolves through the Core contract, the same calling code runs on Core, Pro, or Enterprise — an edition upgrade never rewrites integration code.
Design background: Open core, no lock-in.
Public API surface
Section titled “Public API surface”composer require nextpdf/enterprise:^3The supported integration points are the tenant context (hasScope, hasAnyScope, singleTenant), the API-key generator (generateLive, generateTest, validateChecksum, hashKey, isLiveKey, isTestKey), the API-key authenticator (authenticate, requireScope), the API-key repository interface, the quota checker (check), the tenant-quota value object, and the metering-sync adapter interface. Provide durable repository and billing-adapter implementations for production.
Code sample — quick start
Section titled “Code sample — quick start”use NextPDF\Enterprise\SaaS\ApiKey\ApiKeyAuthenticator;use NextPDF\Enterprise\SaaS\ApiKey\ApiKeyScope;
$tenant = $authenticator->authenticate($request->header('X-API-Key'));$authenticator->requireScope($tenant, ApiKeyScope::Write);
// $tenant->tenantId is now safe to use as the billing/metering subject.Code sample — production
Section titled “Code sample — production”use NextPDF\Enterprise\SaaS\Quota\QuotaChecker;use NextPDF\Enterprise\SaaS\Quota\QuotaExceededException;
$checker = new QuotaChecker($usageMeter, $logger, $alertCallback);
try { $status = $checker->check($tenant, $tenantQuota); if ($status['warning_percentage'] !== null) { $response = $response->withHeader('X-Quota-Warning', (string) $status['warning_percentage']); }} catch (QuotaExceededException $e) { return $this->quotaExceeded($e->resetsAt); // 100% — reject with reset instant}Edge cases & gotchas
Section titled “Edge cases & gotchas”- Checksum is not security. A passing checksum only means the key is well-formed; authentication still hashes and looks it up and enforces revocation and expiry.
- Timing-safe comparison. Key verification uses constant-time comparison; do not reintroduce a short-circuiting string compare in a wrapper.
- Tenant identity provenance. Never construct a tenant context from a client-supplied header or query value; resolve it from authenticated context only.
- Quota warn vs reject. 80% warns and lets the request proceed (with a warning percentage); 100% rejects with the reset instant. The alert callback should deduplicate per period.
- Sync resilience. A metering-sync pull failure returns a no-op cycle and preserves the cursor; failed individual events go to the dead-letter callback rather than blocking the cycle.
Performance
Section titled “Performance”Tenant-context checks and checksum validation are constant-time. Authentication cost is one hash plus one repository lookup. The quota check cost is one usage read plus constant-time arithmetic. The metering sync is a batch operation run on a schedule, off the request path.
Security notes
Section titled “Security notes”API keys are stored only as SHA-256 hashes and are never logged in clear text; verification is timing-safe; revoked and expired keys are rejected with distinct outcomes. Tenant identity must come from authenticated context. Short-lived service tokens minted for inter-component calls carry standard registered claims and a short expiry. This page describes behavior only; token-verification internals are not part of the public contract.
Conformance
Section titled “Conformance”- Inter-component service tokens carry the registered claims
iss,aud,sub,exp, andjtiand honor theexpnot-after rule of RFC 7519 (JWT), §4.1.4. - Service tokens use the JWS compact serialization triple of RFC 7515 (JSON Web Signature), §3.1.
- API keys are stored as SHA-256 digests (FIPS 180-4 SHA-256).
Behavior contract
Section titled “Behavior contract”- A tenant is an immutable context (tenant id, resolving source, authorized scopes); identity is always resolved from authenticated context, never from a client-supplied header or query value.
- API-key authentication validates the checksum, hashes with SHA-256, looks the hash up, and rejects unknown, revoked, or expired keys with distinct outcomes; keys are never logged or stored in clear text and verification is timing-safe.
- The quota checker warns at 80% through the caller-supplied callback and rejects at 100% with a quota-exceeded condition carrying the reset instant (next month boundary, UTC).
- A metering-sync pull failure returns a no-op cycle and preserves the per-source cursor; failed individual events route to the dead-letter callback rather than blocking the cycle.
- The checksum is a typo-rejection convenience, not a security mechanism.
Publication boundary
Section titled “Publication boundary”This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.
Core fallback
Section titled “Core fallback”NextPDF Core (Apache-2.0) has no tenancy, API-key, or quota surface — none; this capability has no Core-tier equivalent.
Pro fallback
Section titled “Pro fallback”NextPDF Pro has no tenancy, API-key, or quota surface — none; this capability has no Pro-tier equivalent. The tenant context, API-key authentication, quota checker, and metering-sync adapter ship in the nextpdf/enterprise package only.
Enterprise boundary note
Section titled “Enterprise boundary note”API-key generation, checksum, and timing-safe verification are described at the behavior level. The token-verification internals, the key-hash storage strategy, and the billing-provider adapter internals are out of scope for the public surface; the billing provider integration is an interface and is swappable.
Deployment boundary
Section titled “Deployment boundary”The operator owns the API-key repository, the billing-provider adapter implementation, the authoritative usage source the quota checker and metering sync read, and the alert-callback deduplication. Tenant identity must originate from authenticated context the operator configures (token, mutual-TLS, or API key). NextPDF Enterprise does not itself persist keys or usage.
Legal-compliance boundary
Section titled “Legal-compliance boundary”No export-control restriction applies to the SaaS surface. API keys and tenant identifiers may be sensitive; storage scope and retention are the operator’s compliance responsibility. This documentation is not a legal opinion; consult your own compliance and legal advisers.