Policies

Data and security

Where your files live, how long links last, how keys are stored, and who to tell about a leak.

Read as Markdown

What RiffAds stores, how long it keeps it, and how to keep your keys safe.

Where files live

  • Outputs are copied into RiffAds storage (Cloudflare R2) when a job finishes. Only that copy is served.
  • Provider links are never stored or returned.
  • Every file sits under your workspace. The workspace comes from your key or connection, never from request input.
  • Files are private. They are served only through short-lived signed links with Cache-Control: private, no-store. No public URLs.
  • Finished outputs never expire.

Your files are never posted anywhere

No code path publishes to Meta, TikTok, YouTube or X. Files leave only when you or your agent fetch a signed link.

LinkLives for
Output link on REST, MCP and the CLI10 minutes (output_urls_expire_in_seconds: 600)
Upload PUT link5 minutes, one use

Agent links are short because they end up in model transcripts.

Expired link is not a lost file

Read the generation again for a fresh link. A stale URL returns 403. Don't retry it.

  • url is null until the generation is finished. Branch on status, not on the URL.
  • If signing fails, url is null, not an error. Read again.

What else is kept

ThingKept
Generation recordsKept. Deleting a project does not delete its generations or outputs.
Content check recordA SHA-256 fingerprint of the input. Never the words.
Abandoned upload reservationCleared after 15 minutes.
Revoked API keyDisabled, never deleted, so history shows which key started which job.

There is no self-service workspace deletion.

API keys

  • Shown once. The database stores a hash. Nobody at RiffAds can recover it. Lost it? Revoke it and create another.
  • Live only. No test keys, no sandbox. Every key can spend what its scopes allow.
  • Never expire. Revoke to stop one.
  • Made in the app. Owners and admins create and revoke keys at app.riffads.com/api-keys. No endpoint creates, lists or rotates keys, so an agent can't issue itself one.
  • Name a workspace, not a person. Want per-person tracking? One key per person or system.
  • No IP allowlist. The key is the whole credential.

Revoking works on the very next call. Work already running still finishes and is charged.

Keys belong on servers

Never put sk_live_... in browser code, mobile apps, public repos, CI logs or chat prompts. Whoever reads it can spend until it is revoked.

No CORS on the REST API

/api/v1 sends no CORS headers and has no OPTIONS handler. On purpose. Call it from a server, task runner, CI job or terminal. Never from a browser.

MCP is different: it allows CORS, because its token comes from an OAuth sign-in, not a secret key. Connect MCP.

CLI key file

riffads login saves ~/.riffads/config.json with mode 0600. RIFFADS_API_KEY in the environment wins over the file. riffads logout deletes the file only. The key still works until you revoke it. CLI setup.

Read-only access

  • A key without the generate or workflows scope can read and estimate, never start work. It is refused before anything is written.
  • A read-only MCP connection does not even see the spend tools.

Use read-only access for dashboards, reports and CI checks.

Tenancy

  • REST: no workspace parameter or header. The workspace comes from the key.
  • MCP: the token is a person, bound to one workspace. Checked again on every call.
  • Another workspace's id and a missing id both return not_found. Nobody can probe what exists.

What never leaves the server

  • Provider names, model keys, prompts, signed URLs and stack traces never appear in an error.
  • Your text is not stored by the content check. Only a fingerprint.
  • Card numbers never reach RiffAds. Checkout runs on the payment provider's hosted page.

Report a problem

Leaked key: revoke it in the app first. It stops on the next call.

Privacy or security report: use the contact address in the Privacy Policy. Legal.

On this page