Projects · Dockerios

SLA compliance by construction

The three Apple SLA rules MacRack exists to enforce, each mapped onto a native Kubernetes primitive that cannot be switched off: two VMs per host as a node resource of two, dedicated chassis as an exclusive lease and taint, and a twenty-four hour minimum as a lease that refuses early reassignment.

Updated Aug 22, 2026 · 9 min read

SLA compliance by construction

A licence rule that lives in documentation gets violated the first time someone is in a hurry. A licence rule that lives in the scheduler, the admission webhook, and the kernel gets violated only by rewriting the operator, which is a decision, not an accident.

MacRack's job is to make the accidental violation impossible. The three rules below are the whole commercial constraint. Everything else in this section exists to serve them.

I am going to say this once more, because it belongs at the top of a compliance page

I am not a lawyer. This is my engineering reading of Apple's published macOS Software Licence Agreement, aligned with how AWS EC2 Mac (24-hour minimum, dedicated Macs) and similar providers already behave.

The SLA can change. Counsel can disagree with my reading. A customer whose use is internal software development on hardware they own is in a different position from a cloud provider selling VMs to strangers. The operator enforces the strict commercial reading, always, with no feature flag that turns the rules off. If a self-hosted internal deployment has a different legal position, that is a conversation with a lawyer, not a Helm value.

The three rules

RuleWhat the SLA requiresWhat the operator does
1. Two concurrent macOS VMs per physical hostUp to two additional copies of macOS in virtual environments on each Apple-branded computer you own or controlEvery Mac node advertises macrack.io/macos-vm: 2. Each instance requests one. The scheduler cannot place a third. The host agent refuses a third. The kernel refuses a third
2. Dedicated chassis per commercial tenantYou do not share the underlying physical Mac across separate paying end-users in a multi-tenant poolA tenant receives a MacNodeLease that taints the entire Mac mini. Customer B cannot schedule onto Customer A's chassis, even if one of the two VM slots is empty
3. Twenty-four hour minimum allocationDedicated hardware hosting for third parties carries a minimum allocation period. AWS EC2 Mac is the existence proof at 24 hoursA lease cannot be released, and the chassis cannot be reassigned, until boundAt + 24h. Deletion before that becomes a hold. Billing runs until the floor

Rule 1: two VMs, three independent stops

I do not trust a single enforcement point. Three layers, each sufficient on its own.

Preparing diagram

The node object is the source of truth for capacity, and it is not configurable:

Why the resource is not a Helm value

The first feature request I will get is "can we set the cap to 4 on the M4 Pro, it has the cores". The answer is no, and the reason the answer is no has to be mechanical.

There is no spec.maxVMs on MacNode. The host agent hardcodes two. The webhook rejects any instance whose resource request is not exactly one. The scheduler is ordinary Kubernetes and does not know Apple exists.

If raising the cap requires a code change, a review, and a release, it will not happen on a Friday afternoon to unblock a customer. That is the point.

Two VMs on one host also have to be distinct machines. Apple's framework requires different machine IDs and different MAC addresses, otherwise only one of them gets a network. The agent generates both at create, stores them on the MacOSInstance status, and will not start two instances that collided. This is not an SLA rule so much as a "the second VM will not actually work" rule, and I treat it as a fourth stop on rule 1.

Rule 2: the chassis is the tenancy boundary

This is the one people get wrong by being too clever. The clever version is "Customer A gets VM 1, Customer B gets VM 2, the Mac mini is well utilised". That is the multi-tenant trap. It is also, coincidentally, the configuration that maximises density and revenue, which is why the operator has to make it unrepresentable.

Preparing diagram

The mechanism is a lease of the whole node, not a placement of a VM.

When the lease binds, the operator:

  1. Removes the macrack.io/unleased taint.
  2. Applies macrack.io/tenant=tenant-acme:NoSchedule.
  3. Applies a matching toleration only to instances in that namespace, through a mutating webhook. Instances from any other namespace cannot tolerate the taint, so they cannot schedule, even if a human edits them.
Empty slots stay empty

A tenant who leases a Mac mini and runs one VM is wasting one slot. That is not a bug. That is the product.

The unused slot belongs to them. They can start a second VM later in the same lease. They cannot sublet it. I cannot sell it to someone else. The utilisation metric I show internally is "leased chassis", not "running VMs", because optimising the second number is how this design gets quietly undone.

If the business cannot make the numbers work at one-to-two VMs per dedicated Mac mini, the business cannot make the numbers work inside this licence. Raising density by mixing tenants is not a pricing lever. It is the thing we are not selling.

Rule 3: twenty-four hours, as a clock the API owns

AWS EC2 Mac's 24-hour minimum is not a vibe. It is how a serious provider already interprets the dedicated-hardware clause. MacRack copies the number, and it copies the behaviour: the clock starts when the lease binds, not when the first VM starts, and it does not stop because the tenant deleted their instances.

Preparing diagram

A Held lease is a first-class phase, not a stuck deletion. kubectl get macnodelease shows Held with earliestReleaseAt, so support can answer "why is this Mac still billed" without reading code.

The webhook rejects any attempt to shorten spec.minimumDuration below 24 hours, and rejects any attempt to patch status.earliestReleaseAt backwards. Status is operator-written. If a controller bug ever writes a shorter floor, the next reconcile puts it back.

Why the clock is on the lease, not the VM

If I put the 24-hour floor on MacOSInstance, a tenant who deletes and recreates VMs inside a lease resets nothing of legal interest, and a tenant who never starts a VM would appear to owe nothing.

The SLA's dedicated-hardware idea is about the chassis, so the clock is on the chassis. VMs inside a lease can come and go. The Mac mini does not go back into the pool until the floor has elapsed.

This also matches how I want to bill: a SKU is "Mac mini, dedicated, per 24 hours", with up to two VMs included. Not "VM-hours", which would recreate the multi-tenant incentive.

What a tenant is allowed to ask for

Putting the three rules together, the consumer-facing API is smaller than DockerIOS, on purpose.

They canThey cannot
Lease one or more whole Mac minis, by class (base, pro, studio)Ask for "a VM on whichever Mac has a free slot"
Run one or two VMs on a leased chassisRun a third, or run a VM on an unleased chassis
Pick an image and a shape that fits the chassisPin two tenants to one serial
Release a lease. If it is before 24 hours, it becomes HeldRelease a lease in a way that makes the Mac available to someone else early

The missing verb, "give me a spare VM", is the product. MacRack does not have a shared VM pool. It has a pool of unleased Mac minis, and a pool of leased ones. Scheduling happens inside a lease, of at most two, for at least a day.

Audit, because enforcement without evidence is a story

Every action that touches a rule writes an event and a record I can export.

EventWhat I store
Lease boundTenant namespace, chassis serial, boundAt, earliestReleaseAt, actor
Instance started or stoppedLease, node serial, instance name, local VM count after the change, machine ID, MAC
Third instance rejectedWhich layer rejected it (webhook, scheduler, agent, kernel), tenant, node
Cross-tenant schedule rejectedSource namespace, target node, target lease tenant
Early delete converted to HeldAttempted at, remaining floor, who asked
Lease actually releasedreleasedAt, duration, confirmation that node is unleased and untainted
The question I want to be able to answer in ten seconds

"Show me that no Mac mini in this fleet ever ran VMs for two tenants at the same time, and that none of them ran three VMs, for the last ninety days."

If the audit log cannot answer that, the enforcement is theatre. So the log is a first-class output of the operator, not an afterthought in a SIEM someone might plug in.

Compliance here is a query, not a feeling.

What I am not claiming

I am not claiming that enforcing these three rules makes every possible use of MacRack lawful. The SLA also talks about the purpose of the virtual copies, software development and testing and personal non-commercial use in the language Apple uses, and a cloud provider's customers may or may not fit that. That is counsel's problem, and the customer's.

I am claiming that the three numerical and tenancy constraints that AWS-class Mac clouds already treat as hard are invariants of this control plane. Nobody gets a third VM, nobody shares a chassis, nobody flips a Mac to a new tenant in an hour. The next page is the API that makes those the only representable states.