Skip to content
pacto

Operational contract system

One versioned contract per service

Ownership, interfaces, version-ranged dependencies, policies and readiness go in one file. Pacto publishes it to any container registry, then compares it against the last revision and against what is actually running.

The demo runs entirely in your browser — about 11 MB, nothing to install. Pacto is for the teams who operate many services; start with what Pacto is.

One versioned contract per service

What is Pacto?

A service's operational facts are scattered. Ownership is in a wiki. The API is an OpenAPI file in another repository. What it depends on is implied by Helm values and a Service name. What breaks if you change it is in someone's memory.

Pacto is an operational contract system. It puts those facts in one YAML file, published to the container registry you already run.

pacto.yaml
pactoVersion: "2.0"

service:
  name: checkout
  version: 4.2.0
  owner: { team: commerce, dri: alice }

interfaces:
  - name: rest-api
    type: openapi
    ref: interfaces/openapi.yaml       # the OpenAPI document you already maintain
    visibility: public

dependencies:
  - name: auth
    ref: oci://ghcr.io/acme/auth-pacto
    required: true
    compatibility: "^2.0.0"            # the range this revision accepts

Who breaks when a dependency ships a new version

The compatibility range above records which versions of auth this revision accepts, and pacto.lock pins every dependency below it to the exact published build. So when auth is about to ship 3.0, Pacto answers per consumer:

$ pacto impact ./auth-2.1.0 ./auth-3.0.0 --local .
Impact: auth 2.1.0 -> 3.0.0
Classification: BREAKING
Breaking changes: 1
Potentially breaking changes: 0
Affected consumers (2):
  checkout                     direct     confidence=contractual  compat=incompatible owner=commerce
  reporting                    direct     confidence=contractual  compat=compatible   owner=analytics

checkout accepts ^2.0.0 and 3.0.0 falls outside it. reporting accepts >=2.0.0 <4.0.0 and 3.0.0 is inside. direct means each one declares auth itself rather than reaching it through another service, and contractual means the dependency is declared with a usable range and nothing observed it running.

One file, checked when you write it, compared against the previous revision, then compared against what is actually running.

When Pacto cannot observe something it says Unknown. It never reports it as a pass.

What each command answers

Command Question it answers
pacto validate Is this contract legal?
pacto diff Did I break my own consumers?
pacto impact Which consumers, and where do they run?
The operator Does reality still match what was declared?

validate and diff pay off at one service; impact and the graph pay off at the second consumer.

Check what is actually running

Pacto can check what a running service actually does on the network against what its contract says, on any Linux machine, and tells you only what it can prove:

What it catches Finding
A process reports healthy but nothing listens on the declared port INTERFACE_ABSENT
A declared dependency the service keeps failing to reach DEPENDENCY_UNREACHABLE
A call to another Pacto service no dependency declares (Kubernetes, pacto agent) DEPENDENCY_UNDECLARED
pacto run --contract ./payments --bind api=8080 --fail-on noncompliant -- ./payments-server

Pacto watches TCP connections in the Linux kernel with eBPF (small, safe programs the kernel runs on events). It never reads payloads or secrets, and when it cannot see it says "don't know" instead of guessing. Run it three ways: pacto run wraps one command (a laptop, a CI job), pacto agent watches a Docker host or a server and the Kubernetes operator deploys the same agent on every node. See Runtime conformance.

Where to start