Security
Last updated: 23 July 2026
Confetti is a small, deliberately narrow Slack app run by TinyPoll. This page is written for the people who evaluate it — including your security and procurement reviewers — and describes exactly how your workspace's data is handled, in concrete terms. Where we haven't built something yet, we say so plainly rather than imply we have.
About Confetti
Confetti announces birthdays, work anniversaries and custom events in Slack, with GIFs, group e-cards and manager alerts. It is built and operated by TinyPoll, the maker of the TinyPoll polling app for Slack. Payments are processed by Stripe and appear on your statement as TinyPoll.
The whole product is one small, single-purpose service: a single AWS Lambda function behind API Gateway, an on-demand DynamoDB datastore, a scheduled job runner, and a static marketing site. There is no always-on server, no admin console, no analytics pixel, and no data warehouse. That narrowness is intentional — it keeps the attack surface and the amount of data we hold both very small.
Data we process
Confetti only stores what it needs to post the right celebration to the right person at the right time, and to bill your workspace correctly.
What we store
- Your Slack workspace ID and name, and workspace configuration (announce channel, timezone, announce hour, message templates).
- Slack user IDs and display names for the people on your roster.
- Birthdays — month and day, plus the birth year only if voluntarily provided.
- Hire / start dates for work anniversaries.
- Manager and reporting relationships, used only for advance manager alerts.
- Group-card messages — the text teammates write when signing a card.
- The Slack bot token, and (only if an admin enables Google sync) a Google refresh token — both encrypted at the field level; see Encryption.
- Stripe customer and subscription identifiers — never card numbers.
What we do not collect or store
- Channel or message history. Confetti's Slack scopes don't grant read access to your conversations, and we never request it.
- Payment card numbers. Card data goes straight to Stripe; it never touches our systems.
- Email addresses. Where a directory or Slack profile exposes an email, we use it transiently — in memory, when matching an imported spreadsheet or directory entry to the right Slack account — and then discard it. We do not store email addresses. (Billable seats are counted from your live Slack member list, not from emails.)
Hosting & data residency
Confetti runs entirely on Amazon Web Services in the Sydney region (ap-southeast-2). Your workspace data is stored and processed there.
When an admin turns on AI-written messages, the only AI inference we perform is pinned to Australian regions — Sydney (ap-southeast-2) or Melbourne (ap-southeast-4). No workspace data leaves AU regions for AI. See AI-written messages for exactly what is sent.
Encryption
In transit. All traffic is encrypted. API Gateway enforces a TLS 1.2 floor, CloudFront redirects the marketing site to HTTPS, and every outbound call we make (to Slack, Stripe, Google, KLIPY and AWS APIs) is HTTPS.
At rest. All workspace data in our DynamoDB tables is encrypted at rest using AWS-managed keys.
OAuth tokens go further. The two most sensitive things we hold — the stored Slack bot token and, if present, the Google refresh token — get an additional layer of encryption at the field level with a dedicated, customer-managed AWS KMS key that rotates automatically every year, cryptographically bound to the workspace it belongs to.
Access control & tenant isolation
- One least-privilege function. A single Lambda runs the whole app, with an IAM role scoped to just the tables, parameters and KMS key it needs — nothing more.
- Strict per-workspace isolation. Every stored record is partitioned by
teamId, and every query is keyed by the requesting workspace'steamId. One workspace's data is never in the query path of another's. - Re-authorization on every change. Mutating actions are re-checked server-side against the caller's Slack admin status at request time — the client is never trusted to assert it.
- No admin HTTP endpoints. There is no back-office web surface to attack; there is no route that returns another workspace's data.
- Health check is blank. The
/healthendpoint returns liveness only and exposes no PII.
Application security
- Signed Slack requests. Every inbound Slack request is verified with an HMAC signature, with replay protection on the timestamp and a constant-time comparison.
- Verified Stripe webhooks. Billing webhooks are rejected unless they carry a valid Stripe signature.
- Short-lived billing tokens. Slack buttons hand off to the browser billing flow via a signed token that expires after one hour.
- Signed OAuth
state. The Slack install flow carries a signedstate/ CSRF parameter that we verify on return, so an install can't be forged or replayed. - AI output is hardened and validated. Prompts sent to the AI model are constructed to resist prompt injection, and the returned text is validated before it is ever posted. Nothing generated is retained.
Secrets management
Application secrets — Slack signing and client secrets, the Stripe secret and webhook secret, Google and KLIPY credentials, and internal webhook secrets — live in AWS Systems Manager Parameter Store as SecureString parameters under a dedicated namespace. They are never committed to source control, never baked into environment variables at build time, and never stored in CI. The KMS key that protects OAuth token fields is separate again.
Sub-processors
Confetti relies on a short, stable list of sub-processors: Amazon Web Services (hosting, in Sydney), Stripe (payments), Slack (the platform itself), Google (only if you enable Google Workspace sync), KLIPY (only if you enable meme GIFs), and AWS Bedrock running Anthropic's Claude (only if an admin enables AI-written messages, in AU regions). The full current list, with what each one processes, is on our Sub-processors page.
Data lifecycle & deletion
- Deletion on uninstall. When your workspace uninstalls Confetti or the token is revoked, we revoke our stored token and delete your workspace's PII. This completes within 30 days, and a daily maintenance job acts as a backstop to catch anything missed.
- Self-serve and admin erasure. Beyond an individual opt-out (which stops a person's dates being used but is not a deletion), admins can trigger erasure of workspace data, and individuals can erase their own — a real removal of the underlying records, distinct from opt-out.
- Billing tombstone. After deletion we retain a minimal billing tombstone (Stripe/subscription identifiers and plan state, no roster PII) as needed for accounting and to prevent trial abuse.
- Announcement log. The idempotency log that stops a celebration being posted twice expires automatically on a TTL of roughly 400 days.
- Backups. DynamoDB point-in-time recovery is enabled, which means a deleted record can still exist in recovery snapshots for up to about 35 days before it ages out. We consider deletion complete when the live data is removed; the recovery window is a normal backup horizon, not active use.
Our Privacy Policy covers retention, individual rights and how to make a deletion or export request.
Logging
We write operational logs to CloudWatch to run the service, with a one-month retention period. We do not log PII or secrets — logs record what happened, not who was celebrated or any token. AWS Bedrock invocation logging is turned off, so AI prompts and responses are not captured in logs either.
AI-written messages
AI-written celebration text is off unless an admin explicitly enables it, which requires an in-app agreement that we record. When it is on, at the moment an announcement posts we send AWS Bedrock (Anthropic's Claude model) only the facts needed to write that one message:
- the celebrant's display name;
- their job title from their Slack profile, if it's set;
- your workspace name;
- the occasion (birthday or which anniversary); and
- the years or age being celebrated — age only when that person has chosen to show it.
We do not send birth dates, emails, message history, or roster data beyond the above. We don't store what's sent or generated; Bedrock does not retain, log or train on prompts or outputs; and requests are processed only in AWS's Australian regions.
Reporting a vulnerability
If you believe you've found a security issue in Confetti, please tell us. Email security@tinypoll.io with enough detail to reproduce it. We'll acknowledge your report — we aim to do so within three business days — keep you updated while we investigate, and let you know when it's resolved. Please give us a reasonable window to fix an issue before disclosing it publicly, and don't access or modify data that isn't yours while testing. We don't run a paid bug-bounty program, but we're grateful for responsible disclosure and happy to credit you.
In short
Confetti is a small, single-purpose service that holds very little data, isolates every workspace, field-encrypts its OAuth tokens with a dedicated customer-managed KMS key, deletes your data on uninstall, and keeps everything in Australian AWS regions. If your security review needs detail beyond what's covered here, email security@tinypoll.io and we'll answer directly.
TinyPoll · security@tinypoll.io · support@tinypoll.io · See also the one-page summary, Privacy Policy and Sub-processors.