drift Docs
Start
What is Drift?
The tour, if you are new here.
Use cases
Whether Drift does your thing.
Getting started
Nothing to deployed, in one command.
Architecture
How a slice is put together.
What it costs
The free grant, four unit prices, two rules.
Build
Canvas
Static sites, same origin as your API.
Tools
Operate
Auth
Accounts, tokens and scopes.
Security
Boundaries, sandboxing and hardening.
Troubleshooting
Error codes
What went wrong, and what to do about it.
Legal
Acceptable use
What a slice may not be used for.
Data processing
The DPA, and every sub-processor.

Atomic functions

The atomic section is where your functions are declared, plus the runtime limits that apply to all of them. functions[] is the whole declaration: what the slice exposes, which callable serves it, what it books and what guards it. Your source carries none of that — it is ordinary source, and the handlers sit in atomic/ as flat files (that flat set is the default element, one language, one backend).

The section carries two keys. Timeouts, the rate limit, deploy history, the storage budget and every function's memory booking belong to the slice and are set in the slice's shape.

TypeDefaultMeaning
  • egress
    Type
    map
    Default
    { mode: open }
    Meaning
    Outbound network posture; see Outbound egress.
  • functions[]
    Type
    list of maps (required if you run any)
    Default
    none
    Meaning
    Every function to deploy. Never inferred: a callable the file does not name is ordinary source and gets no route.

A function's memory is chosen when the slice is shaped, not here.

It is that function's own admission pool and what it is billed at, so it belongs where the slice is sized and priced. atomic.functions[].memory still parses and is ignored. drift file benchmark measures what each function actually costs and prints what it should book; --apply opens the form with those figures filled in.

Declaring functions[]

Every entry is a map, and three of its keys are required: route, method and handler. The rest are optional, and they are how a function gets a gate, its secrets, a schedule or an alert — there is nowhere else to put any of it.

TypeDefaultMeaning
  • route
    Type
    path
    Default
    required
    Meaning
    The path this function answers on, under /api/ping, auth/challenge, groups/:id. For a queue-triggered function it is the queue's name instead.
  • method
    Type
    get post put patch delete head options queue
    Default
    required
    Meaning
    Part of the identity, not a detail: get and post on one route are two functions with two slots. queue means the slice invokes it per message and it has no URL.
  • handler
    Type
    callable name
    Default
    required
    Meaning
    The function in your source that serves this. Looked for in the element's folder only, so two elements may each have a handle. It has to be reachable from outside its file — exported in Go, pub in Rust, a named function in Node.
  • auth
    Type
    none | apikey
    Default
    none
    Meaning
    The gate in front of it. Setting an API key on the route forces apikey whatever this says — the key is the stronger statement. See authentication.
  • stream
    Type
    sse | ws
    Default
    buffered
    Meaning
    Hold the connection open instead of buffering one response. See streaming.
  • secrets[]
    Type
    list of names
    Default
    none
    Meaning
    The Backbone secrets this one function may read. A secret not named here is unreachable from it even though the slice holds it.
  • dir
    Type
    path
    Default
    the element's folder
    Meaning
    Source directory, relative to the Driftfile, for the odd function that lives outside its element's folder.
  • element
    Type
    string
    Default
    the flat element
    Meaning
    The sub-app this function belongs to: the group that shares one language, one dependency manifest, one runtime.
  • cron
    Type
    5-field cron
    Default
    none
    Meaning
    Also run this function on a schedule. It keeps its own trigger; the deploy ships a schedule alongside it.
  • alerts[]
    Type
    list of maps
    Default
    none
    Meaning
    Fire a notification when this function errors. Reconciled against the live alert registry on every deploy.
Driftfile
functions:
    - route: digest
      method: get
      handler: GetDigest
    - route: charge
      method: post
      handler: PostCharge
      auth: apikey                       # demands a key this slice issued
      secrets:
        - STRIPE_KEY                   # the only secret this one may read
    - route: orders                     # no URL; the slice invokes it per message
      method: queue
      handler: HandleOrder
    - route: reconcile
      method: post
      handler: PostReconcile
      element: billing                   # lives with the other billing functions
      cron: "0 3 * * *"                  # 03:00 daily, 5 POSIX fields
      alerts:
        - on: errors                     # errors is the only accepted trigger
          threshold: 5                   # errors within the window
          window: 5m                     # minimum 60s
          notify: webhook=https://hooks.example.com/drift

cron is a 5-field POSIX expression; the parser checks the field count and the scheduler validates the grammar, so a malformed expression surfaces at deploy. An alert needs window and notify, and both are errors if missing. threshold defaults to 1, on to errors, and window must be at least 60 seconds. The only notify form is webhook=<http(s) URL>.

The deploy writes every alert the file declares. One that is live and no longer declared is left in force and named in the report apply prints at the end of a run — a slice can serve more than one project, so a deploy cannot tell an alert that is not yours from one you dropped. Take it away with drift atomic alert remove <name>.

Outbound egress

atomic.egress declares which hosts your functions may reach. It is the source of truth for the allowlist; drift atomic egress list/refresh/test inspect what the slice has, and there is no CLI verb to add a host.

Driftfile
atomic:
    egress:
      mode: allowlist                  # open (default) | allowlist
      hosts:
        - api.stripe.com
        - "*.amazonaws.com"            # accepted, then skipped: name concrete hosts
        - smtp.sendgrid.net:587        # host:port; port defaults to 443

An allowlist is declared, not yet enforced.

The deploy prints that in as many words when it applies one. Treat the block as a statement of intended reach and keep whatever authentication and secret hygiene you would have used without it. Private ranges are a separate matter and are blocked: RFC-1918, link-local and CGNAT egress is refused from a slice whatever mode says.

Read the Atomic guide → for how to write a function.