Open source · MIT · runs on Kubernetes

Every team's automation, one workflow. Nobody's credentials shared.

Vennir runs DAGs of container steps as Kubernetes Jobs. Each step is a product your platform teams published and reviewed, running as its own identity with only its own team's secrets, and handing its outputs to the next.

Try it on your laptop See how a run works
$ vennir init dev && vennir apply dev
New service: refunds-api order for payments · 4 steps · 3 teams · 2m 00s
Waiting on approval
project.create platform as gcp-project
Succeeded · 41s · projectId → next
cloud-sql.create data-platform secret: db-admin
Succeeded · 1m 09s
app-hosting.create payments needs approval
Waiting on a maintainer
ticket.open payments
Waiting for app-hosting
12:04:53 cloud-sql.create · INFO instance refunds-db starting
12:06:02 cloud-sql.create · INFO instance refunds-db ready
12:06:03 app-hosting.create · waiting for a payments maintainer
Installs with one CLI where Kubernetes runs
kind, on your laptop Google GKE Amazon EKS your own cluster
How it works

Platform teams publish. Everyone else orders. The cluster keeps it honest.

Today the script that makes a project, the one that makes a database and the one that deploys an app live in three repos with three sets of credentials. Vennir makes each one a product, and lets anyone chain them, without handing anyone the keys.

  1. 01 · Publish

    A product is a container and a contract

    Each team keeps its products in a catalog repository. CI builds, tests, scans and signs every image, then publishes one signed release that every install pulls.

  2. 02 · Order

    Pick what you need, it wires itself

    Add actions to a cart, and Vennir plans the order: which step feeds which, what to reuse, what to ask once. Or run a template, call the API, or let a bot order for your storefront.

  3. 03 · Run

    Each step in its own team's namespace

    The scheduler starts each step as a Kubernetes Job once the steps before it finish, passes their outputs in, retries what's safe to retry, and waits for an approval where one is needed.

teams/data-platform/products/cloud-sql/product.yaml the contract
apiVersion: vennir.dev/v2
kind: Product
name: cloud-sql
team: data-platform
serviceAccount: gcp-cloud-sql   # its own identity
actions:
  - name: create
    idempotent: true          # safe to retry
    maxAttempts: 3
    shareWith: ["*"]
    input:
      required: [projectId, name]
      properties:
        projectId: {type: string}
        name: {type: string}
    output:
      properties:
        connectionName: {type: string}
teams/payments/dags/new-service.yaml the DAG
apiVersion: vennir.dev/v2
kind: Template
name: new-service
steps:
  - id: project
    action: project.create
    inputs: {name: {$param: service}}
  - id: database
    action: cloud-sql.create
    dependsOn: [project]
    inputs:
      projectId: {$fromStep: project, $output: projectId}
      name: {$param: service}
  - id: app
    action: app-hosting.create
    dependsOn: [project, database]
    inputs:
      projectId: {$fromStep: project, $output: projectId}
Security

Every step fenced in, by the cluster itself.

The console checks every rule, and admission policies in the cluster check them again, so going around the console gets you nowhere. Each refusal comes back with a code that says why.

  • Its own identity

    A step runs as the ServiceAccount its product declares, and reaches its cloud by short-lived federation, not a stored key.

    IDENTITY_NOT_ALLOWED
  • Only the secrets it lists

    A team's secrets live in its own namespace. Only its reviewed products can mount them, and each step only the ones it names.

    secretRefs, per step
  • Reviewed images only

    Every image is pinned to its digest, scanned before it runs and, where you require it, signed by catalog CI.

    IMAGE_NOT_PINNED · IMAGE_SCAN_FAILED · IMAGE_NOT_SIGNED
  • Inputs and outputs checked

    Each action's schemas are enforced at submit, before a step starts and when it finishes, so a bad value stops where it entered.

    INPUT_INVALID · OUTPUT_INVALID
  • Approvals where they matter

    A product can ask for a maintainer's yes before it runs, always or only for some teams, and allow targets per team.

    TARGET_NOT_ALLOWED
  • A record nobody can rewrite

    Every call is in a hash-chained audit log, copied to a bucket that refuses deletes and compared with the database entry by entry, a few at a time, round and round.

    audit.export
Ordering

Order from the console, your CI, or your own storefront.

  • A catalog and a cart. Readiness on this install shown on every product, run forms made from each action's schema.
  • Keyless bots. Your CI job signs in with its own OIDC identity; no stored token.
  • Ordering bots with signed callbacks. A storefront orders only the templates it's allowed, and hears back when each order finishes.
  • Ask Vennir. A chat agent that answers from your docs with citations and proposes a cart; you place the order.
POST https://orders.acme.com/vennir signature verified
# What your storefront receives when an order finishes
Vennir-Signature: t=1793331200,v1=5d1f…c09a

{
  "type": "order.finished",
  "executionId": "c2382f0a-2c11-480b-bd96-4f09b5f39a5e",
  "state": "SUCCEEDED",
  "finishedAt": "2026-10-30T12:09:14Z"
}

# v1 = HMAC-SHA256 of "<t>.<body>" with the bot's secret
Observe

See every run, and only what you should.

Logs, by who may read them

INFO lines to everyone who can see the run; the rest to the step's own team. Credentials are redacted before anything is kept.

Failures explained by their owners

A product says what its error codes mean, what to do, and whether a retry is safe, right on the failed step.

Metrics without a metrics stack

Waits, failures and step times from Vennir's own tables, and Prometheus alerts when you want them: your operator, a bundled one, or your cloud's managed service.

What every run made

The project, the database, the service: recorded with what depends on what, so nothing is deleted out from under something else.

Install

One CLI, and you see the bill before anything changes.

vennir asks a few questions, checks your tools and your cloud sign-in, and shows an approval screen with everything it will create and an estimate from your cloud's own prices. Then it installs, and can sleep, wake, back up and restore what it made.

Download vennir Read the setup guide
vennir apply prod
$ vennir apply prod

  Target       gcp · GKE Autopilot · us-central1
  Size         resilient
  Database     Cloud SQL, backed up daily
  Logs         searchable 30 days, then archived
  Monitoring   Managed Service for Prometheus
  Catalog      acme/platform-catalog, signed

  Estimated    [FROM YOUR CLOUD'S PRICE LIST] a month

  Apply these changes? [y/N] y
  ✓ Cluster, registry, identities
  ✓ Kernel and console installed
  ✓ Console at https://vennir.acme.com

Try it on your laptop in a few minutes.

A kind cluster, a local registry, the console and a first team; make catalog-publish then adds the sample products, one in five languages.

$ git clone https://github.com/rburns629/vennir && cd vennir && make quickstart
Star it on GitHub Read the docs
Vennir is 0.x: read what is and isn't enforced yet in the security model.