Status
Proposed on 2026-03-14 by Lars Solem.
Context
Dataverket now has proposed decisions for:
- a public API owned by Sentral
- NATS-based orchestration with tenant and project metadata
- separate domain services for compute, networking, Kubernetes, identity, and storage
What is still missing is a single resource hierarchy that all of those systems can share. Without that, API design, authorization, billing, inventory, and event correlation will drift apart.
Decision
Dataverket adopts the following tenancy and resource hierarchy:
Tenant The top-level administrative and billing boundary.
Project The primary ownership and quota boundary within a tenant.
Environment An optional but first-class deployment boundary within a project.
The standard resource scoping model is therefore:
- tenant -> project -> environment -> service resources
Why this hierarchy
This model is chosen because it gives Dataverket:
- a clean billing boundary at tenant level
- delegation and quota control at project level
- safe separation between dev, stage, prod, and similar deployment contexts at environment level
It is also a better fit than project-only scoping for a platform expected to host networks, clusters, databases, applications, and long-running infrastructure tasks.
Resource classes
Dataverket manages two broad resource classes:
Platform inventory resources
These represent infrastructure Dataverket itself owns and operates.
Examples:
- sites
- rooms
- racks
- switches
- routers
- BMC endpoints
- physical servers
- uplinks
- VLAN pools
- IP pools
These resources are not tenant-owned. They are operator-managed inventory and capacity inputs used by the control plane.
Tenant-facing service resources
These are resources allocated to or created for tenants, projects, and environments.
Examples:
- virtual machines
- bare-metal allocations
- Kubernetes clusters
- databases
- buckets
- applications
- logical networks
- VPN endpoints
- load balancer allocations
These resources carry tenant and project ownership, and environment scope where applicable.
Ownership rules
Ownership rules are:
- every tenant-facing resource must have a
tenant_id - every tenant-facing resource must have a
project_id - resources that participate in deployment separation should also have an
environment_id - platform inventory resources must never pretend to belong to a tenant
Some shared services may be project-scoped without being environment-scoped. Examples include:
- a shared container registry namespace
- a long-lived object storage bucket used across environments
The API and database schema must therefore allow environment_id to be nullable where the resource type justifies it.
Inventory model
Sentral owns the global resource inventory and resource graph.
Within Sentral, inventory should still be treated as its own strongly isolated context with its own schema boundary rather than as just another set of tables behind the API facade.
The inventory model must support:
- physical topology
- resource capacity
- resource allocation state
- ownership links
- dependency links between resources
The inventory model must also support safe concurrent mutation and allocation behavior. Inventory is not only descriptive; it is used to make exclusivity-sensitive decisions about placement, reservation, and capacity.
Examples of dependency links:
- a cluster depends on servers or VMs
- a VM depends on a hypervisor host and a network
- a network allocation depends on a VLAN and IP pool
- a database depends on a cluster, storage, and a network policy
Allocation consistency implications
Because inventory drives allocation, the platform must distinguish between:
- descriptive updates that can use optimistic conflict handling
- exclusivity-sensitive reservations that require transactional protection
Resources such as servers, VLANs, IP pools, and other finite allocatable capacity must not be double-assigned because two workflows observed stale state at the same time.
This inventory graph is the backbone for orchestration, impact analysis, and future billing.
Canonical resource identifiers
Every resource must have:
- a stable internal UUID
- a resource kind
- a human-meaningful name scoped appropriately
Names must be unique within the right boundary, not globally across the whole platform.
Recommended uniqueness rules:
- tenant names: globally unique within Dataverket
- project names: unique within a tenant
- environment names: unique within a project
- service resource names: unique within their project or environment scope as appropriate
Authorization model implications
Authorization should follow the same hierarchy:
- tenant-level roles for administrative and billing authority
- project-level roles for ownership and daily operations
- environment-level permissions for deployment isolation where needed
Operator roles for managing platform inventory remain separate from tenant roles.
No user should gain access to infrastructure inventory simply because they can manage tenant-facing resources.
API implications
The public API should reflect the hierarchy directly.
Representative path shapes:
/v1/tenants/{tenantId}/v1/tenants/{tenantId}/projects/{projectId}/v1/projects/{projectId}/environments/{environmentId}/clusters/v1/projects/{projectId}/networks/v1/projects/{projectId}/tasks/{taskId}
The exact path design may evolve, but the scoping semantics must stay aligned with this tenancy model.
The hierarchy must also support tenant onboarding and first-use flows. A tenant administrator should be able to move from tenant scope to project scope to environment scope without relying on hidden naming conventions or one-off bootstrap scripts.
Event and task implications
NATS messages and task records must carry:
tenant_idwhen the action concerns tenant-facing resourcesproject_idfor project ownershipenvironment_idwhen the resource is environment-scoped
Operator-only inventory workflows may omit these fields when no tenant boundary applies.
Billing and metering implications
Billing aggregation should happen at tenant level, with detailed attribution at project and resource level.
This enables:
- tenant invoicing
- project quota enforcement
- environment-aware usage reporting where useful
Consequences
- Dataverket gets a consistent hierarchy for API, auth, billing, and orchestration
- environment becomes a first-class concept instead of ad hoc naming convention
- inventory and tenant resources are clearly separated
- some resource types will need explicit rules for whether they are project-scoped or environment-scoped
- Sentral’s inventory graph becomes a critical shared dependency
- onboarding flows can be modeled as explicit creation and policy-validation steps within the same hierarchy instead of as out-of-band setup
Decision Outcome
Proposed. This ADR records the current preferred direction and still needs acceptance before it becomes binding.
More Information
- task resource schema and lifecycle
- quota model
- billing and metering model
- naming and slug rules for public resources
Audit
- 2026-03-14: ADR proposed.