# Security policy ## Reporting a vulnerability Please do not open a public issue for a security problem. Email **info@privatae.ai** with: - the version (`privatae-bastion version`) and platform, - what you found and how to reproduce it, - what an attacker could do with it. You will get an acknowledgement within three business days. We will keep you informed as the report is confirmed and fixed, and credit you in the release notes if you wish. ## What is in scope - This repository: the `privatae-bastion` binary and the installers under `deploy/`. - Anything that lets a host, another machine, or another user on the same machine do more than the grant and the local approval allow: reading files outside a granted store, deleting where only archiving is allowed, running a program that is not in the fixed table, bypassing the second factor, opening a listener that is not documented in the security model ([docs/security-model.md](docs/security-model.md)). ## What is out of scope - The Privatae platform the bastion connects to. It is separate software with its own reporting path; reports about it sent to the address above are forwarded. - Findings that require root on the machine already. The bastion's root ops assume the machine's administrator is trusted. ## Supported versions Only the current release, as published in the release manifest, receives fixes. The bastion self-updates from that manifest, checks the manifest's signature, and checks the digest of what it installs against it, so a fixed release reaches every paired machine when its host directs the update. ## What you still have to trust The bastion limits what your host can do on your machine. It cannot limit what the bastion itself does, and the bastion comes from us. These are the places where you are trusting us, and what stands in the way. **The release key.** Every release manifest, for the bastion and for the agent it runs, is signed with an ed25519 release key. The public halves are compiled into the binary (`client-go/release_sign.go`), and a manifest that does not verify is refused. The private key never comes to the machine that builds and publishes releases: a release is built there, then waits until the key holder signs it on their own computer with `deploy/release-sign`, where the key is stored encrypted under a passphrase. Whoever holds that key and passphrase can publish a bastion and an agent that every bastion will accept. A compromised download server, cache or DNS record is not enough on its own: without the key it can only serve something the bastion refuses. The release machine is different. It builds the release and computes the digest the key holder signs, and the signing program shows only the kind, the version and that digest, which the key holder has no independent way to check at that moment. So someone in control of the release machine could have a substituted release signed during a normal publish. That would not stay hidden: `deploy/verify-release.sh`, run from any clone of this repository, rebuilds the published release and reports any binary that differs. But it is found after publishing, not stopped before it. Two keys are pinned, a primary and a spare kept offline apart from it. If one is lost, releases are signed with the other, and a later release pins a new spare. If both were lost, no bastion could take another update or agent until it was reinstalled by hand. **The first install.** `curl … | sudo sh` and `irm … | iex` run a script from our website before any bastion exists to check anything. The installer checks the binary's digest against the manifest, but the installer and the manifest come from the same place. To avoid trusting that one download, build from source (see the README) or run `deploy/verify-release.sh` before installing. **Bastion updates.** A bastion never replaces itself on its own. Your host has to ask, and what it can ask for is limited to what we signed: the update goes ahead only when a signed manifest names exactly the version the host asked for. On a machine anchored to a host, a move to a newer version needs no approval from you, so there the signature is the only thing that stands in the way, as it is for the agent below. A signature shows that we published a manifest at some point, not that it is the latest one, so a move to an older version, or to one the bastion cannot compare with its own, still needs your approval bound to that exact version. On a local machine that is not anchored, your host can move the bastion to an older signed release by asking. Switching `directives` off in the local console refuses every update your host asks for. **Agent updates.** The agent is different: it updates without asking. While a folder is shared with the agent, the bastion checks the agent's manifest every ten minutes and installs any newer signed version, restarting the agent on it, with no request from your host and no approval from you. The signature is the only thing that stands in the way. A new agent version reads the folders you granted, as the old one did, and is never moved to an older version than the one installed. **Checking our work.** Release builds are reproducible. `deploy/verify-release.sh` fetches the published manifest, checks its signature, checks out the release's source, rebuilds it, and compares every binary's digest. From 0.43.0 on, each public snapshot in this repository carries the annotated tag `v`, whose message records the release's `built_from`. That field names the commit in the repository the release was built in, which is not a commit here, so the script uses the tag and prints which source it used. If the digests match, this source builds the binaries we serve. Releases published before build reproducibility was added (0.40.0 and earlier) cannot be checked this way. **The agent.** The bastion downloads the bastion agent, runs it, and gives it the folder you granted. The agent is a separate program in its own repository (`privatae/bastion-agent`), and it reads your files in order to index them. What leaves your machine is what its manifest and your grant allow. Its extraction and PII redaction happen inside it, so check that repository, not this one, for how well those work. **The platform.** Your host runs on our platform, which is not open source. The bastion keeps the host to your grant and your approvals whatever the platform does. What the host does with what you share with it is governed by software you cannot read here.