Infrastructure from code.
With an exit.

Write a marker in your code. The scanner derives the infrastructure that must exist, provisions it least-privilege on Google Cloud, and resolves it back to the exact call that asked for it. What is provisioned and what is consumed cannot drift apart.

import { db, cloudrun } from "@rabiamakhoul/fluffy-chainsaw";

const users = db.connect("users");  // build time: "users must exist"
                                    // runtime: the least-privilege connection

cloudrun.entrypoint("orders-api", (req, res) => {
  res.end(`connected as ${users.user}`);
});

That's the whole model: markers are both the build-time declaration and the runtime lookup. Databases, buckets, pub/sub, secrets, auth — same pattern. And when you want out, fluffy-chainsaw eject hands you the standalone Pulumi program it was running all along. No lock-in, verifiably.

You own the infrastructure

fluffy-chainsaw is a tool, not a platform. Everything runs in your Google Cloud project:

No lock-in — down to the client library

The wrapper SDKs are conveniences, not a cage. Every marker also resolves as a plain metadata descriptor, so Google's own client works against the same provisioned resource — and every wrapper client has an unwrap() escape hatch.

// the wrapper SDK
import { storage } from
  "@rabiamakhoul/fluffy-chainsaw-storage";

const media = storage.bucket("media");
await media.put("avatar.png", buf);
// the raw Cloud SDK — same marker
import { Storage } from "@google-cloud/storage";
import { storage } from "@rabiamakhoul/fluffy-chainsaw";

const d = storage.bucket("media"); // descriptor
const b = new Storage().bucket(d.name);
await b.file(d.prefix + "avatar.png").save(buf);

What a marker buys you

Pick a capability — left is the code and config you write, right is what deploying it provisions. Full resource + IAM ledger in each example's README.

import { db } from "@rabiamakhoul/fluffy-chainsaw-db";

const users = await db.connect("users");
// a ready pg.Pool — IAM token auth handled inside
databases:
  users: { instance: app-db, extensions: [pgcrypto] }
instances:
  app-db: { tier: db-custom-1-3840 }
runners:
  api:
    uses: { databases: [users] }

provisions

  • Cloud SQL · Postgres — zero-default-access database, IAM token auth, no password exists
  • IAM binding — the runner's own identity, scoped to this database only
import { storage } from "@rabiamakhoul/fluffy-chainsaw-storage";

const signups = storage.bucket("waitlist");
await signups.put(`${id}.json`, body);
buckets:
  waitlist: { location: US }
runners:
  site:
    uses:
      buckets:
        - { name: waitlist, prefix: signups/, writer: true }

provisions · this page's real config

  • Cloud Storage · waitlist — US multi-region bucket
  • IAM conditionstorage.objectAdmin scoped to the signups/ prefix, not the whole bucket
import { pubsub } from "@rabiamakhoul/fluffy-chainsaw-pubsub";
import { pubsub as core } from "@rabiamakhoul/fluffy-chainsaw";

const orders = pubsub.topic("orders");
await orders.publish({ orderId, item });

core.subscription("/events", async (msg) => {
  await handle(msg.data); // return = ack, throw = redeliver
});
topics:
  orders: {}
  failed: {}
runners:
  worker:
    trigger:
      subscriptions:
        - { topic: orders, path: /events,
            dead_letter: failed, max_retries: 5 }

provisions

  • Pub/Sub topicsorders, failed; publishers get pubsub.publisher on their topic only
  • Push subscription — private OIDC subscriber; a public one is a build error
import { auth } from "@rabiamakhoul/fluffy-chainsaw-auth";

app.post("/api/login", auth.handler);   // Google + GitHub
app.get("/api/profile",
  auth.requireSession(),                // 401 without a session
  (req, res) => res.json(req.session.user));
auth:
  engine: firebase
  providers: [google, github]
  session: { ttl: 7d }
runners:
  app:
    uses: { auth: true }

provisions

  • Identity Platform — Google + GitHub sign-in, one account per email
  • Session cookies — HttpOnly, server-signed; requireSession() gates every write
import { realtime } from
  "@rabiamakhoul/fluffy-chainsaw-realtime";

// broadcast a typing signal to the room
await realtime.channel(room).send("typing", { user });
realtime:
  engine: firebase
runners:
  app:
    uses: { realtime: true }

provisions

  • Realtime Database — Firebase RTDB instance + rules deployed from config
  • IAM access — member-gated private channels, no open read/write path
// Go (Golang) SDK
cloudrun.Scheduled("/jobs/fortune", func(w http.ResponseWriter, r *http.Request) {
  f := fortune()
  realtime.Channel("fortune").Send(r.Context(), "latest", map[string]any{"text": f})
  w.Write([]byte(f + "\n"))
})
realtime:
  engine: firebase
  instance: a-fluffy-chainsaw-fortune
runners:
  fortune:
    uses: { realtime: true }
    trigger:
      http: true
      schedules:
        - { path: /jobs/fortune, cron: "0 * * * *" }

provisions

  • Realtime Database — Firebase RTDB instance + hourly scheduler
  • Cloud Scheduler — calls /jobs/fortune hourly to fetch a new fortune
// Go (Golang) SDK
uploads, _ := storage.Bucket("uploads")
jobs, _ := pubsub.Topic("thumbs-jobs")

// api writes uploads and publishes jobs
uploads.Put(r.Context(), key, imgBytes, storage.ContentType(ct))
jobs.Publish(r.Context(), map[string]any{"key": key})
buckets:
  uploads: { location: US }
  thumbs: { location: US }
topics:
  thumbs-jobs: {}
runners:
  api:
    uses:
      publishes: [thumbs-jobs]
      buckets:
        - { name: uploads, prefix: img/, writer: true }
        - { name: thumbs, prefix: img/, viewer: true }

provisions

  • Cloud Storage · uploads & thumbs — two multi-region buckets
  • Pub/Sub topicthumbs-jobs trigger topic
  • IAM conditions — split reader/writer bucket permissions across api and worker
# fluffy-chainsaw.yaml declares a bucket…
buckets:
  waitlist: { location: US }

# …but no code declares storage.bucket("waitlist")
$ fluffy-chainsaw scan
[E_NOT_IN_CODE] fluffy-chainsaw.yaml configures
"waitlist" under "buckets" but code declares no
such resource — remove it or add the marker

refuses to emit

  • config with no matching marker → E_NOT_IN_CODE
  • database bound to no server → E_DB_UNBOUND
  • db.connect(tenantId) — a name the scanner can't resolve statically → build error, never silent under-provisioning
  • public runner with a push subscription → E_SUB_PUBLIC_RUNNER
  • unknown field, wrong type, out-of-set enum → source-pointing error. Drift isn't monitored — it's unrepresentable.

This page is the demo

This site is itself a fluffy-chainsaw app — one runner, one bucket, deployed by the tool it's describing (push to main → provisioned). Its entire configuration:

buckets:
  waitlist:
    location: US

runners:
  site:
    uses:
      buckets: [{ name: waitlist, prefix: signups/, writer: true }]
    trigger: { http: true }
    build: { target: site }

Every capability above is a runnable example — browse all examples or read this site's own source.

Want us to host it for you?

Deploy to your own Google Cloud project today — or join the early-access list for managed hosting: we run it, you keep the eject button.

One email when early access opens — nothing else, ever. Want your address gone? Email us and it's deleted.

Built in the open. GitHub