The customer runtime
The customer runtime lets you run a vendor's application inside your own AWS account, with no connection to a TALOS Defence service while a job is running. You pay for a licence and support, and you pay AWS for the instances.
The customer runtime runs a vendor's release inside your own environment. You get the same release, the same envelope and the same signed return as on the hosted pools. The envelope is the set of limits that TALOS Warrant compiles before a job starts. The runtime is hangar-api --profile customer, the same program as the hosted service, with a [customer] table in its configuration.
While a job is running, the runtime connects to no TALOS Defence service. The runtime checks the licence offline. The runtime compiles each envelope. The runtime signs each return under your root key. Everything that the runtime imports arrives on media that you control.
1. What the runtime keeps
| Item | Where it comes from |
|---|---|
| The customer organisation and its pool | [customer]: the organisation's id, legal name, ABN and country of control, and the pool's id and name from its registration (POST /v1/pools). Every return shows the pool identity that the registration gave. |
| The root | Your own key site. The key set shows your organisation as the issuer. |
| TALOS Defence's published key sets | Three files: the release key set (releases, acceptances and revocation lists), the entitlement key set (licences) and the record key set. |
| The licence | The licence file, and any later licence in a site snapshot. |
| Releases | Release bundles, each imported by an owner. |
| The revocation list | Inside each release bundle and each site snapshot. |
2. Starting the runtime
- Register the pool on the hosted service and receive its licence (Pools, Section 3.4).
- Place the licence file and TALOS Defence's three published key sets on the runtime's storage. Name the files in
[customer](Configuration). - Set the
[sandbox]rates to0. The capacity is your own, on your own AWS bill. - Run
hangar-api --profile customer --selftest. The itemcustomer runtimechecks the files, the root and the licence. - Run
hangar-api --profile customer --first-owner NAME --email EMAILonce. The command prints a one-time value that enrols the first owner's passkey. - Start the service with
--profile customer.
The runtime sends no mail, so the runtime has its own sign-in: the person's passkey alone. The browser offers the passkey without a typed address. The hosted service's sign-in, a code by email and then the passkey, is not available in the runtime.
At start, the runtime makes these checks in this order. The runtime refuses to serve when one check fails:
- Root custody. The runtime's key set names your organisation as issuer. The key set shares no root with TALOS Defence's record, release or entitlement key sets. TALOS Defence keeps only the release key and the entitlement key.
- The organisation and the pool. The first start writes both, each with a record. A later start compares both with
[customer]. - The licence. TALOS Defence's entitlement key must sign the licence. The licence must permit this AWS account, name this pool and this organisation, and have a term that has begun.
3. The licence
The runtime checks its licence at start and once a day, offline. The runtime sends no report to TALOS Defence. A renewal is a new file. Replace the licence file, or import a site snapshot that contains the new licence. The runtime keeps the licence with the highest serial.
| Licence state | Jobs of installed releases | Release imports | New tenants |
|---|---|---|---|
| In term | Allowed | Taken | Taken, up to the licensed count |
| Lapsed, in the 90-day grace | Allowed, and each return states the lapse | licence_lapsed | Taken, up to the licensed count |
| Lapsed, past the grace | Allowed, and each return states the lapse | licence_lapsed | licence_grace_ended |
The licence's package count and tenant count are limits. An import of a new package past the package count gives licence_limit_reached. A tenant past the tenant count also gives licence_limit_reached.
4. Importing a release
POST /v1/runtime/releases takes a release bundle as hex. The bundle comes from GET /v1/releases/{id}/bundle. The request can also name a local channel:
{ "bundle": "a5...", "channel": "stable" }
An owner's import is the local approval of the release. The release runs in the runtime only after the import. The import moves the channel when the request names one. The runtime checks the bundle offline against TALOS Defence's release key set, or against a rotation of that key set that the root signed. The runtime checks these four things:
- the vendor's signature on the release;
- TALOS Defence's acceptance;
- the revocation list in the bundle;
- the package manifest, against the digest that the signed release names.
If you import the same bundle again, the runtime answers with the release. The widening rule (Releases) applies in the runtime, and your owners are the approvers.
5. Importing a site snapshot
POST /v1/runtime/snapshot takes a site snapshot as hex. The snapshot comes from GET /v1/pools/{id}/snapshot. The snapshot must be for this pool. The snapshot's key sets must be the configured key sets or a signed rotation of them. The runtime then imports the snapshot's revocation list and licence.
A revocation list replaces the list that the runtime holds only when its sequence is higher. Each imported list revokes the local releases that the list names, and the runtime refuses a job of a revoked release. The runtime keeps out a list with a lower sequence. The runtime refuses another list with the same sequence as the held list.
GET /v1/runtime gives the runtime's organisation, pool, issuer, licence, revocation list and policy.
6. Jobs and returns
A job starts on the runtime's own pool. The job takes the hosted path. TALOS Warrant compiles the envelope before anything starts. Each attempt is a fresh instance. The job returns once.
Before a job starts, the runtime reads the age of its revocation list. Under the policy refuse, the runtime refuses the job with revocation_list_stale when the list is older than the maximum age. Under the policy record, the job goes ahead.
Every return from the runtime has these three features:
- The return shows your organisation as issuer, and your day keys sign the return under your root.
- The return states the licence's state and the revocation list's age when the job started.
- The return shows the pool, with the identity that the pool's registration gave.
A person verifies the return offline with your key set and TALOS Defence's release key set: hangar verify --issuer-keys. You can import a return into the pool on the hosted service with POST /v1/pools/{id}/returns. The hosted service checks the return again against the pool's licence and policy.
7. The installation check
hangar-api --profile customer --verify-install DESCRIPTION checks a description of the deployed account, as your read-only role reads the account. The description lists the security groups and their inbound rules, the buckets, and the roles with their trust policies.
The command writes an installation report as a record on the runtime's platform chain, prints the report, and exits 0 only when every item passed. A description that leaves out the security groups, the buckets or the roles fails. A policy that the check cannot read also fails. The report names each item that fails:
- a security group with an inbound rule from any source outside the private ranges, or from a prefix list;
- a bucket without versioning, or a data or records bucket without object lock;
- a role that trusts a principal outside your account, in its principal, by
NotPrincipal, or in a condition; - an operator session role (form B) that is not limited to 12 hours, or that does not deny, with no condition, every S3 action on each data and records bucket, its objects and its access points, and every KMS, CloudHSM and Secrets Manager operation.
The report also states the licence and whether the root answers. Under not_checked, the report lists the items that you check by your own means: the artefact digests and boot measurements against the signed runtime release, and the live account.
8. The diagnostics export
hangar-api --profile customer --diagnostics-preview prints every field of the export. --diagnostics-export FILE writes the same fields to a file. The runtime signs the file with its day key and adds the day key's attestation, so the file checks offline against your key set. You send the file through your own channel. The export contains:
- the runtime's version and the migrations applied, with their digests;
- each configuration key's name, with a keyed digest of its value;
- the self-test items, passed or failed;
- the licence's serial and state, and the revocation list's sequence and age;
- job outcomes, and job and attempt reason codes, with their counts, and attempt timings;
- record counts by kind;
- each tenant as a keyed digest, with its state and job count;
- the imported releases, by release id, package and version.
The keyed digests use a key that the runtime draws for each export and then drops. A short value therefore cannot be found by hashing guesses. The export reads no input, output, secret, configuration value, tenant reference or tenant name.
9. What the runtime serves
The runtime serves these things:
- jobs, their events, returns and artefacts;
- tenants, request keys, uploads and objects;
- sandbox sessions and their secrets, approvals and certificates;
- the worker plane and the runtime's own
/v1/runtimeroutes.
The Python package (gethangar) and the CLI work against the runtime when you set the endpoint.
Booking, payments, sign-up, mail, pool registration, licences, release submission and the operator plane belong to the hosted service. In the runtime, these routes answer not_in_this_runtime. On the hosted service, /v1/runtime answers runtime_only.
10. Errors
| Code | Status | When |
|---|---|---|
not_in_this_runtime | 404 | The hosted service at api.gethangar.au serves the call. |
runtime_only | 404 | A customer runtime serves the call. |
licence_lapsed | 409 | The licence's term has ended, so the runtime takes no new release. |
licence_grace_ended | 409 | The licence ended more than 90 days ago, so the runtime takes no new tenant. |
licence_limit_reached | 409 | The licence supports no more packages or tenants. |
release_import_invalid | 422 | The bundle does not check against the release key set, or the package manifest is not the manifest that the release names. |
snapshot_invalid | 422 | The snapshot does not check, or is for another pool. |
revocation_list_stale | 409 | The held revocation list is older than the policy allows, under the policy refuse. |
release_revoked | 409 | The release is on the held revocation list. |