Skip to content
Skip to content
PGB Learn

Function secrets, webhooks and logs

Keep keys out of your code, protect a function with a signed webhook, and read or limit its execution logs.

Updated Nov 12, 2026

Keep secrets out of your code

Never paste an API key into function code. Add it as a secret and read it at runtime.

There are two places:

  • Per function: in the function dialog, Environment Secrets (JSON), for example {"STRIPE_KEY": "sk_..."}. These are stored encrypted.
  • Project-wide: in the sidebar under Configuration, choose Secrets & Env, then + Add Secret. Enter a Secret Key Name (such as STRIPE_API_KEY) and a Secret Value, then Save & Encrypt Secret. Project secrets are encrypted, shown as dots in the list, and automatically available to your functions and your containers.

Inside a function, read them from env:

export default async function handler(req, { env }) {
  const key = env.STRIPE_API_KEY;
  // ...
}

Once saved, a secret's value is never shown again. To change it, add it again with the new value.

Protect a function that others call

A function with the HTTP / Webhook trigger can be called by anyone who knows its address, so treat it like a public page. Two things help:

  • Check the caller in your code. The request is available to your handler, including its headers and raw body. For a service that signs its webhooks (a payment provider, for example), keep the provider's signing secret in Secrets & Env and verify the signature in your function before doing any work.
  • Use PGB's signature check. If a request carries an X-PGBHub-Signature header, in the form t=<unix timestamp>,v1=<hash>, it is verified against the function's signing secret: v1 is a hash over <timestamp>.<raw request body>. A wrong or missing signature is refused with 401, and a timestamp more than five minutes old or in the future is refused, which stops replayed requests. A function whose trigger type is a webhook requires this header on every call.

If you only need to keep strangers out, you can also limit which addresses may call your project on the Network Access page. Calls from other addresses are refused.

Read the logs

Choose Logs next to a function, or Execution Logs at the top of Functions Studio. The page shows total invocations, success rate and average duration, and a table of runs with request and response details and the output your function printed. You can filter by function.

Function logs are stored in your database and count toward your storage. Use the settings on the logs page to control this:

  • Record All Runs
  • Errors Only (Save Space)
  • Disabled (0 Storage)
  • Purge Old Logs to delete older history. You can also set how many days of logs to keep (from 1 to 365; the default is 30).

All services also appear together under Unified Logs in the sidebar.

Good to know

  • Secrets are encrypted at rest and only decrypted when a function runs.
  • A function that fails returns its error message and appears as Error in the list.
  • Python functions run in a restricted sandbox and can import only a short list of standard modules (such as json, re, datetime, math, hashlib, base64 and uuid). Importing anything else fails with a clear message.
  • Turn logging down for very busy functions to save storage.

More guides in Console: functions, cron & jobs