lbreeze
\← All articles

The resource model

Thirteen typed resources, one lifecycle, and a plan that is only a bundle of grants.

Everything kstack manages is a typed resource, and every type implements the same lifecycle.

provision / update / suspend / unsuspend / deprovision / observe

That is the whole interface. It is why "sell one mailbox" and "sell a 200-site reseller plan" run the same machinery.

The types

domain, dns_zone, dns_record, website, ssl_cert, database, db_user, mailbox, mail_domain, forwarder, ftp_account, cron_job, backup_policy.

How they are owned

account  (parent_account_id -> reseller tree, quota pool)
  └── subscription -> plan -> resource_grants[]
        └── resource (typed)

An account can have a parent, which is what makes a reseller tree a tree rather than a special case. Quota pools follow the same shape.

A plan is a bundle of grants

A plan does not describe a product in prose. It grants a number of each resource type, and its kind decides which grants are even allowed.

Kind May grant
shared_hosting, reseller_hosting anything
database database, backup_policy
email mail_domain, mailbox, dns_zone
dns dns_zone
vps vm, backup_policy, private_network

A grant the kind does not sell is refused with a 400 naming the grant, rather than accepted and ignored.

Isolation

The website is the isolation unit — not the account. One unprivileged, id-mapped system container per site. A customer with five sites has five boundaries, so a compromise of one does not reach the other four.

Databases are deliberately not per-customer containers. They are shared instances on database nodes, with a per-customer database, user and grants. A container each would hold the same engine in memory once per customer, and at density that cost is not recoverable.

Was this helpful?
Still stuck? Contact support.