Reference and concepts

Release discipline.
Debian-native fleet delivery.

Version the inputs, test the artifacts, approve their hashes, and distribute owner-signed APT repositories. Keep host management with Debian and your existing automation.

Open the task-oriented guide

Install TPA

The published source is https://tpa.run/r/tparun/bootstrap/ (browse packages). The deb822 source file below contains an embedded PUBLIC signing key, not a private key or account credential.

curl -fsSL https://tpa.run/tparun.sources -o /tmp/tpa-bootstrap.sources
cat /tmp/tpa-bootstrap.sources
# Extract and inspect the embedded public key:
sed -n '/^ -----BEGIN PGP PUBLIC KEY BLOCK-----/,/^ -----END PGP PUBLIC KEY BLOCK-----/p' /tmp/tpa-bootstrap.sources \
  | sed 's/^ //; s/^\.$//' > /tmp/tpa-bootstrap.asc
gpg --show-keys --with-fingerprint /tmp/tpa-bootstrap.asc

# ONLY after independently confirming the publisher fingerprint:
sudo install -m 0644 /tmp/tpa-bootstrap.sources \
  /etc/apt/sources.list.d/tpa-bootstrap.sources
sudo apt update
sudo apt install tpa=0.8.0
tpa version

Expected bootstrap fingerprint: EDCEE63AA803737C8ABBC1E4A34190A2829D5E54. On arm64 or riscv64, change the source's Architectures: field to the output of dpkg --print-architecture before installation. Never use trusted=yes or disable HTTPS/signature verification.

The published package is tpa, including tpa-utils and tpa-release. This bootstrap does not currently publish the TPA.run backend package; do not assume apt install tparun is available from it.

Nix-inspired does not mean a Nix replacement

TPA brings explicit package definitions and identifiable release artifacts to a native Debian workflow. It is not a Nix store, a derivation evaluator, an isolated-build guarantee or a whole-system configuration engine. Reproducibility must be established by the build and its qualification.

Use dpkg and APT for installed packages and dependencies, SSH for existing access, and systemd for services where available. Your inventory and configuration-management tools select hosts and rollout policy. TPA.run is the release-distribution layer, not a fleet control plane.

TPA builds and signs on the owner side. TPA.run authenticates, authorizes, receives, verifies, deduplicates, activates and serves finished content. Neither ordinary SSH hosting nor TPA.run builds or signs on behalf of the owner.

Follow a canary-to-fleet rollout

The publisher signs. You choose trust.

Repository owners sign APT metadata locally with their selected OpenPGP key. TPA.run may verify the public signature, but never requires the owner's private key, replaces the signature or signs on the owner's behalf.

Current bootstrap publisher fingerprint:

EDCEE63AA803737C8ABBC1E4A34190A2829D5E54

Verify this identity independently before trusting the source. Keep normal APT signature and HTTPS verification enabled. A rendered website, JSON inventory or webhook is not an additional signing authority.

gpg --export OWNER_FINGERPRINT > owner-public.gpg
tpa verify --require-signed -keyring ./owner-public.gpg \
  -fingerprint OWNER_FINGERPRINT ./finished

Approve hashes. Sign on a separate device.

A private stage binds the repository, publisher, expected parent generation and complete artifact manifest. Build/test devices upload already-finished DEBs. On the owner device, inspect each package identity, size and SHA256, and compare the stage manifest digest with the original trusted build manifest.

The current tpa sign command takes that approved release-manifest.json, fetches and rechecks the exact artifacts, derives repository metadata locally, signs with the owner key and publishes through SSH-CAS. Changed or missing bytes fail; packages are not rebuilt after approval. A hash identifies bytes, not whether testing or review succeeded.

The stage covers the complete next repository snapshot. Include other required artifacts; it is not an implicit merge with the current generation. An intervening publication makes the pinned parent stale rather than silently rebasing the release.

This uses the published TPA 0.8.0 CLI with owner-side signing. Hosted stages do not replace any separately configured GitHub approval gate.

See the two-device workflow

Prepare packages and derive the repository

Create a package tree with tpa init, manage its payload directories, then build the .deb. Package artifacts are authoritative; APT indexes and website sidecars are derived from them. tpa compose is the separate metadata-only JSON/JSONL workflow, not a replacement for payload trees.

tpa init -name example -ver 1.0 -arch all \
  -maintainer 'Example <example@example.invalid>' \
  -desc 'Example package' -out ./package
# Add your payload files to ./package.
tpa build -in ./package -out ./artifacts/example_1.0_all.deb
tpa pack -in ./artifacts -out ./finished -gpg OWNER_FINGERPRINT

tpa pack --empty -out ./empty-repository creates the canonical empty tree. Package identity remains Package + Version + Architecture.

Publish a finished repository

Build and sign a complete repository on your own machine with TPA. TPA.run receives, verifies, stores and serves the original bytes, including index.html and repository.json. It does not build packages or sign on your behalf.

Before publishing, complete SSH identity registration and confirmation, obtain repository ownership and a publishing entitlement from your operator, and authorize your owner's public APT signing certificate. Pin the server SSH host key in your SSH configuration. An operator browser session alone does not grant publishing authority.

# Owner-side preparation; replace OWNER_FINGERPRINT with your signing identity.
tpa pack -in ./artifacts -out ./finished -gpg OWNER_FINGERPRINT
gpg --export OWNER_FINGERPRINT > owner-public.gpg

# Replace HOST, PORT and REPOSITORY_ID with your provisioned destination.
tpa publish -in ./finished \
  --output=tparun+ssh://tparun@HOST:PORT/REPOSITORY_ID \
  -ssh-config ./ssh-config -keyring ./owner-public.gpg \
  -fingerprint OWNER_FINGERPRINT -json

For an update, add -parent-generation CURRENT_GENERATION using the current active generation. After an interrupted or uncertain activation, inspect the active generation before retrying. Never send your private signing key to the hosting server.

Canonical receive-only hosting does not accept the legacy tparun stage / tparun publish package-ingestion workflow. Use a qualified TPA client with tpa publish. TPA is available from the canonical tparun/bootstrap repository; the backend package is a separate release.

Ordinary SSH or SFTP

An ordinary SSH server needs no TPA.run identity service, CAS receiver or signing key. TPA builds/verifies a local candidate and transfers original files to a new remote destination.

tpa pack -in ./artifacts \
  --output=ssh://publisher@HOST/absolute/new-repository \
  -ssh-config ./ssh-config -gpg OWNER_FINGERPRINT

Existing remote replacement is not supported by this strategy. Do not confuse it with TPA.run's generation activation.

Identity, SSH capabilities and permissions

A session identifies your account. Entitlements set resource limits. Repository ownership or an explicit scoped delegation authorizes publication. None of these grants operator authority.

Manage public SSH keys in your account workspace. Keys added to existing accounts start disabled. Initial registration instead commits the permissions selected during passkey enrollment and original-key SSH confirmation. Personal Browser Login permission is separate from Read, List and Write. Never put a private key into a form or enable browser login on a CI key.

SSH browser login

ssh -p 2222 -i ~/.ssh/personal tparun@HOST login

This feature requires explicit Browser Login permission. The short-lived, single-use HTTPS fragment must be confirmed by its owner. Do not share that link or log its ticket. It creates ONLY an account session, never operator access.

Operator access

Operator sign-in is passkey-only, using the registered operator WebAuthn credential. Account passkeys and SSH browser tickets never become operator sessions. Normal login does not require a replacement passkey or extra password.

Client-generated repository websites

TPA produces index.html and canonical repository.json from APT indexes. TPA.run distributes those uploaded bytes unchanged through the same repository path as dists/ and pool/. The account workspace and bootstrap installation guide are trusted host UI, not another repository renderer or signing authority.

On the single hosting origin, only exact deployment-approved explorer assets may run inline. Unknown or modified owner files remain opaque attachment downloads with restrictive content policy. Publisher-supplied hashes never grant script-execution authority. Private readers, APT metadata, signatures and package bytes use the same authorization and serving boundary.

No additional content domain is required for this deployment. Other installations may retain separately configured legacy viewer routing; migrate existing links and clients deliberately rather than silently changing origins.

Usage, quotas and publication history

Use your workspace for owned repositories, SSH credentials and capacity. Repository workspaces read the existing canonical usage and bounded history APIs; operator views add independently authenticated administration.

Active logical bytes
Original file lengths in the active generation.
Unique CAS payload
Unique object payload bytes, including retained objects; not filesystem or database overhead.
Uploaded / reused
Verified payload receipt for the last accepted generation; not encrypted SSH wire overhead.
HTTP egress
Observed response body bytes, with accounting uncertainty reported separately.
Quotas
Server-owned resource policy, never a source of repository or operator authority.

Limits and enforcement

Account resource grants bound storage and transfer work. Canonical storage includes all original active files: packages, APT metadata, signatures and websites. Physical deduplication does not reduce logical quota. Pending reservations are separate; replacement admission does not simply add them to active bytes. HTTP enforcement and metrics-only observation are distinct delivery modes; a plan label is not a publishing permission or live purchase offer.

Missing measurements are shown as unavailable. An empty repository is not an error. A failed or uncertain publication is not reported as active merely because its upload started.

Self-hosting

The core runs as tparun serve. Canonical receive-only hosting uses tparun-hosting / 1 and stores finished content; no host builder, host signing service, external billing provider or dashboard is required.

TPARUN_PROFILE=self-hosted \
TPARUN_CUSTOMER_ORIGIN=https://tpa.example.invalid \
TPARUN_CUSTOMER_RP_ID=tpa.example.invalid \
TPARUN_OPERATOR_ORIGIN=https://tpa.example.invalid \
TPARUN_OPERATOR_RP_ID=tpa.example.invalid \
TPARUN_REPOSITORY_ORIGIN= \
TPARUN_DATA_DIR=/srv/tparun/data \
tparun serve

Provision TLS for this one origin and route it to the existing application. No content domain, additional repository service or cross-origin browser communication is needed for download-only distribution. Keep existing production RP IDs and origins unchanged unless separately migrating them. Operator first enrollment uses the protected bootstrap file; ordinary later sign-in reuses the same registered passkey. Do not reset an existing canonical database.

Optional webhooks and TPA.run updates

Qualified RC5+ development contains durable, at-least-once notifications for repository updates/deletion, storage and usage. The existing operator webhook manager supports destinations, subscriptions, delivery history, retries and safe event inspection after passkey authentication. Hooks are not required for core hosting and cannot authorize commands or deployments.

The independent signed-APT updater is separately privileged, fixed-policy and opt-in. Installing its package does not enable it. Review its source/package/public key, backups, native architecture and recovery policy before any administrator-authorized activation. Never supply deployment commands through an event body.

This website does not configure a webhook destination or consumer, enable Stripe, or activate the privileged updater. Those remain separate operator decisions.

Receiver, CLI and automation are separate releases

Receiver reference · 31 Oct 2026

Staged upload support

The last verified baseline is TPA.run 0.1.5~rc11+stagequota.a50d6e2. The pilot deployment adds passkey-protected finite increases to existing local allowances and complete logical-storage display; it does not activate billing. Authenticated staged-upload and existing finished-repository SSH-CAS negotiation were verified. This is not a claim that a GitHub release was approved or published.

Published bootstrap

TPA 0.8.0

The canonical bootstrap contains that CLI for amd64, arm64 and riscv64, including stage and owner-local sign. Keep the original package bytes and signing key under owner control; do not assume a receiver upgrade updates clients.

Separate authorization

Fleet and CI policy

CI credentials, signing-device access, independent approval and host rollout policy must be configured explicitly. No fleet reconciliation service, automatic installation or updater activation is implied by this website.