Skip to content

amittell/agentcli-demo

Repository files navigation

agentcli Demo

End-to-end demonstration of agentcli governing a real deployment pipeline. Provisions infrastructure via Stripe Projects, deploys a Next.js storefront with Stripe payments to Vercel, monitors operations with per-task least-privilege Stripe API keys, and produces a cryptographic proof-of-custody audit trail.

What This Demonstrates

  • Multi-workflow manifests with identity profiles, contracts, and evidence
  • Compilation to multiple runtime targets (standalone, openclaw-scheduler)
  • Identity resolution -- different principals per task, enforced before execution
  • Least-privilege identity split for both Stripe (restricted keys) and Vercel (readonly vs deploy)
  • Infrastructure provisioning via Stripe Projects (Neon Postgres + Vercel)
  • Governed deployment -- every CLI operation wrapped in agentcli with attestation
  • Payment monitoring with per-task scoped Stripe restricted API keys
  • Full audit trail with SHA-256 command hashes and SSH signatures

Prerequisites

Tools

Tool Version Purpose
agentcli >= 0.2.0 Manifest governance, identity, execution
stripe CLI latest Stripe Projects provisioning, test triggers
vercel CLI latest Deployment (wrapped by agentcli)
node >= 22 Next.js app runtime
jq >= 1.7 JSON output formatting
curl any Health check verification
SSH key ed25519/rsa Evidence attestation (uses ~/.ssh/id_*)

Accounts

Account Purpose
Stripe (test mode) API keys, restricted keys, payment triggers
Neon Postgres database (provisioned via Stripe Projects)
Vercel Hosting (provisioned via Stripe Projects)

Environment Variables

Create .env in the repo root with the following keys from your Stripe account (test mode):

STRIPE_API_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_KEY_CHARGES_READ=rk_test_...
STRIPE_KEY_BALANCE_READ=rk_test_...
STRIPE_KEY_PAYMENT_INTENTS_READ=rk_test_...

The three rk_test_ keys are restricted API keys created in Dashboard > Developers > API keys > Create restricted key, each with a single permission:

Key Permission
STRIPE_KEY_CHARGES_READ Charges: Read
STRIPE_KEY_BALANCE_READ Balance: Read
STRIPE_KEY_PAYMENT_INTENTS_READ PaymentIntents: Read

The webhook secret comes from stripe listen --print-secret.

Additional credentials (DATABASE_URL, VERCEL_TOKEN) are provisioned automatically by Stripe Projects during Part 4 of the walkthrough.

Architecture

File Structure

agentcli-demo/             # this repo (github.com/amittell/agentcli-demo)
  manifest.json            # agentcli manifest (4 workflows, 5 identities)
  walkthrough.sh           # automated demo script
  walkthrough.md           # manual step-by-step guide
  manifests.md             # plain-English manifest reference
  README.md                # this file
  FUTURE-WORK.md           # recording TODOs
  .env                     # Stripe keys (manual, gitignored)
  next.config.js           # Env passthrough (DATABASE_URL, STRIPE_* to runtime)
  app/                     # Next.js 15 App Router pages
    page.js                # Storefront product grid
    admin/page.js          # Admin dashboard (charges + balance)
    orders/page.js         # Order history
    checkout/              # Success + cancel pages
    api/
      checkout/route.js           # Stripe Checkout session creation
      health/route.js             # Health check (DB + Stripe)
      orders/route.js             # Order list API
      webhooks/stripe/route.js    # Webhook handler (signature verified)
    components/
      buy-button.js        # Client component for checkout
      nav.js               # Shared navigation
  lib/
    db.js                  # PrismaClient (standard connection, no adapter)
    stripe.js              # Stripe SDK initialization
  prisma/
    schema.prisma          # Product + Order models
    seed.js                # 4 demo products
    migrations/            # 0001_init
  agentcli-demo/           # Created by stripe projects init (gitignored)
      .env             # Stripe Projects credentials (auto-pulled)
      .projects/       # Stripe Projects state

Identity Profiles

The manifest defines 5 identity profiles with least-privilege separation:

ID Provider Principal Trust Purpose
project-admin none agent://demo/project-admin supervised Stripe Projects provisioning
stripe-ops stripe-api-key agent://demo/stripe-ops restricted Payment monitoring (3 scoped keys)
database-admin env-bearer agent://demo/database supervised Database migrations
vercel-readonly env-bearer agent://demo/vercel-readonly restricted Deployment inspection, health checks
vercel-deploy env-bearer agent://demo/vercel-deploy supervised Deploy writes, credential sync

The stripe-ops profile uses the stripe-api-key provider with precreated restricted keys. Each task gets a different key scoped to only the Stripe resources it needs:

Scope Permission Key Env
charges_read Charges: Read STRIPE_KEY_CHARGES_READ
balance_read Balance: Read STRIPE_KEY_BALANCE_READ
payment_intents_read PaymentIntents: Read STRIPE_KEY_PAYMENT_INTENTS_READ

The Vercel identity is split into vercel-readonly (restricted, read-only inspection) and vercel-deploy (supervised, deployment writes). Same least-privilege pattern as Stripe.

Workflows

ID Name Tasks Identity Purpose
provision Provision Infrastructure 4 project-admin init, add neon, add vercel, pull credentials
deploy Deploy Application 7 mixed sync creds, migrate, deploy, inspect, verify health, verify payments
stripe-ops Stripe Payment Operations 3 stripe-ops (scoped) list charges, check balance, list failed payments
cleanup Teardown Demo Environment 1 vercel-deploy remove Vercel project

Evidence

All tasks produce SSH-signed evidence binding the execution ID, declared identity, command, and result into a canonical JSON payload. This creates an unforgeable chain tying every operation to the principal that ran it.

Contracts

Each workflow and task can declare a contract specifying:

  • sandbox: execution isolation level
  • network: network access policy
  • audit: whether the execution must be audited
  • required_trust_level: minimum trust level for the task's identity
  • trust_enforcement: advisory (warn) or strict (fail if violated)

The deploy workflow uses strict enforcement on deploy-app and run-migrations, meaning agentcli will refuse to execute them if the identity's trust level is insufficient.

Running the Demo

Automated (recommended)

# Full run -- provisions, deploys, transacts, audits
./walkthrough.sh

# Full JSON output (verbose mode)
./walkthrough.sh --verbose

# Skip provisioning (infra already up)
./walkthrough.sh --skip-provision

# Skip provisioning and deployment (app already live)
./walkthrough.sh --skip-provision --skip-deploy

# Tear down everything for a clean re-run
./walkthrough.sh --cleanup

The script is idempotent -- re-running skips already-provisioned resources. Cleanup is comprehensive: Stripe Projects services, Vercel project (via agentcli), local state, and audit log.

Manual

See walkthrough.md for a step-by-step guide with every command.

App Stack

Layer Technology
Framework Next.js 15 (App Router)
UI React 19 + Tailwind CSS v4
Database Neon Postgres (via Prisma, standard connection)
Payments Stripe Checkout (redirect flow)
Hosting Vercel
Provisioning Stripe Projects
Governance agentcli v0.2

Troubleshooting

"Interactive prompt rendering unavailable" when adding Vercel : The Vercel OAuth flow requires a terminal. Run the command directly: stripe projects add vercel/project --accept-tos --yes --config '{"name":"agentcli-demo"}'

"Project already exists" on Vercel add : A previous Vercel project with that name still exists. Run cleanup first: ./walkthrough.sh --cleanup

Identity resolution fails for deploy tasks : Credentials not loaded. Run stripe projects env --pull from the agentcli-demo/ subdirectory, then source the .env.

Trust level mismatch on run-migrations : The database-admin identity must have supervised trust to match the run-migrations contract's required_trust_level: supervised.

NEON_CONNECTION_STRING vs DATABASE_URL : Stripe Projects pulls credentials as NEON_CONNECTION_STRING. The walkthrough script aliases it to DATABASE_URL in load_env(). For manual runs, export it: export DATABASE_URL="$NEON_CONNECTION_STRING"

Stripe Projects vault sync on sandboxes : stripe projects env --pull may skip resources and leave .env empty on sandbox accounts. The walkthrough script has a 3-tier fallback: (1) normal pull, (2) re-add services to force credential sync, (3) API debug extraction via --debug flag.

Vercel runtime env vars : Vercel serverless functions do not load .env files at runtime. Env vars must be set in Vercel project settings using vercel env add (requires vercel login with personal auth, not the Stripe Projects vca_ token). The next.config.js env passthrough handles build-time injection as an alternative.

Prisma/Neon adapter on Vercel : The @prisma/adapter-neon driver adapter has initialization timing issues on Vercel serverless. Use standard PrismaClient with the Neon connection string directly -- it works as a standard Postgres URL. The demo uses this approach in lib/db.js.

Vercel team OAuth linking : Each Vercel team can only be linked to one Stripe account. If you get "Team is already linked to a different Stripe account", disconnect Stripe from the old account in Stripe Dashboard > Installed Apps.

About

agentcli demo app -- provisioned by Stripe Projects, governed by agentcli

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors