Privacy policy
This policy explains what Staygreen stores, why, for how long, and what you can ask us to do about it. It describes what the software does today, and where something isn’t automatic yet, it says so.
Who is responsible
HURYN Sp. z o.o.
ul. Hoża 29, 00-521 Warszawa, Poland
KRS 0000893173, NIP 7011027727, REGON 388627882
Data protection enquiries: contact@staygreen.io
HURYN Sp. z o.o. is the controller for the data described here. We have not appointed a Data Protection Officer; we are not required to.
Who Staygreen knows about
Builders sign in and set up apps, monitors and status pages in a workspace. Alert recipients get a workspace’s alerts: its members by email, and the people and Telegram chats a member added. Visitors read a builder’s status page without an account. Staygreen doesn’t keep subscriber lists yet, so it holds no subscriber’s address.
If you are a builder
Your account, meaning your email address, your name if your sign-in method provides one, how you sign in, and the workspaces you belong to, is held by Clerk, our sign-in provider, which also sends the emails that sign you in and records the browsers you sign in from to protect your account. Each workspace is a Clerk organization, and Clerk holds its name and its members too. Our own database stores only Clerk’s identifiers: your organization’s, on the workspace, and yours, beside each incident update you write, beside a count of the tests you ran recently, and beside each alert sent to you. We read your name from Clerk when an update’s author is shown, and your email address and time zone when an alert is sent to you, and never copy them into our database.
What a workspace holds:
Stripe and Supabase monitors store your supplied key encrypted with AES-256-GCM, never display it again, and delete it with the monitor. Requests send it only to Stripe's API or your named Supabase project. Stripe supplies event payloads during a poll; Staygreen discards their customer data and keeps only event identifiers needed for recovery, types, counts, creation times and endpoint status in failure evidence. Supabase response bodies are discarded; only service status and a refused-check marker are kept. These vendors process requests under your account with them.
- Apps: a name, an address, a logo and a brand colour. A logo is an image you choose, or your app’s own site icon when Staygreen suggests its checks; either way only its pixels are kept, at two sizes, with no metadata. The colour is the one found on your app’s site when Staygreen suggests its checks, and a new status page starts with it.
- Monitors: a name, what each checks (an address, a host and port, or a DNS record), its schedule, the keyword and assertions it looks for, and whether it is paused. Header values you add to a monitor are encrypted (AES-256-GCM) before they are stored, are never shown again, and are deleted with the monitor.
- Heartbeat URLs: a hash of each heartbeat’s token, which is how its pings are recognised, and an encrypted copy, so your workspace’s admins can see the URL again on the monitor’s page.
- Check results, which are never stored one by one. For each monitor we keep 5-minute summaries from each location (how many checks ran, how many failed, and their response times), a total for each day, every change of state, and the last 20 failed checks, each with its reason and what the check saw: for an HTTP check, the status and at most 300 bytes of the response, masked (below); for a certificate, its expiry, issuer and name; for a DNS record, every answer each resolver returned, in full and not masked, since those are public DNS records.
- Incidents: when each opened, was acknowledged and closed, the locations that saw it, the request, why it failed (for a DNS record, with the answers a resolver returned), the assertion that failed and what it got, and the masked snippet of the response; and the updates you write, with their author’s Clerk identifier. An update stays private until you publish it.
- What your jobs send to a heartbeat: nothing yet. Nothing receives heartbeat pings yet, so nothing a job sends reaches Staygreen.
- Alerts: where they go, and a receipt for every message. For the members’ email, a receipt holds the member’s Clerk identifier, never their address, and the workspace keeps the identifiers of members who turned their own alert email off. An address a member added is stored as typed, with who added it and when it was confirmed or unsubscribed; until it is confirmed, only a hash of its confirmation link is kept. A Telegram chat is stored as Telegram’s identifier for it and the name Telegram gave us when it was connected: a group’s title, or the person’s @username or name. Each receipt holds what it was about, when it was sent or why not, and the message’s identifier at Postmark or Telegram. Email and chat message text is built again from the incident. A signed webhook keeps its masked payload on the receipt for consistent retries.
- Status pages: a name, an address, logo text, a homepage link (at first, the app’s address), a colour and a theme, an uploaded logo and favicon (only their pixels), and the components you put on the page with the monitors behind each.
Masking. Before a response snippet or the value an assertion got is stored, one masker replaces email addresses, bearer tokens, JWTs, API keys, long hex or base64 strings, values under names such as password or token, and your monitor’s own header values with •••. It works by recognising patterns, so keep personal data out of the responses you monitor rather than relying on it. DNS answers aren’t masked.
What checks send, and from where. The servers that run checks send requests from Toronto (Canada) and San Francisco (US), to the targets you add, on each monitor’s schedule: an HTTP request with the method and headers you set, a TCP connection, or a TLS handshake to read a certificate. HTTP requests identify themselves as StaygreenBot/1.0, unless you set a User-Agent header of your own, which replaces it. They send the headers you stored, a Cookie header too if you stored one, and add no cookie of their own. The site you monitor sees those requests and our servers’ IP addresses, as it would any visitor’s. A DNS monitor asks Cloudflare’s and Google’s public resolvers for the record you name. When you test a monitor before saving it, or Staygreen suggests an app’s checks from its address, the requests go from our hosting provider’s servers instead, each time you do it, within the dashboard’s limit on tests; what comes back is shown to you and not stored, except a site icon kept as the app’s logo and the brand colour found on its site, kept with the app. The StaygreenBot page says what each check sends.
Scheduled checks haven’t started for new workspaces yet: until they do, a monitor you add isn’t checked and has no results.
Legal basis: performance of a contract (Art. 6(1)(b) GDPR). You asked us to watch your apps and publish what you choose.
If you get alerts
A workspace’s members who can see its monitors get its alerts at the email address their Clerk account holds, with times in the time zone Clerk has for them, or in UTC. An alert names the app and the monitor, says what failed with the masked evidence and the locations that saw it, and links to the incident and the status page; a second message follows when it recovers. Someone without an account gets alerts only at an address a member added, and only after confirming it from the one email we send there first; an address not confirmed within 7 days gets nothing more unless a member sends it a new link. A Telegram chat gets alerts once a member opens a one-time link in it and presses Start.
Stopping them. Every alert email has a link that stops them, with no sign-in, and mail apps that offer their own unsubscribe button use the same link. A member can turn their alert email back on in the dashboard. Sending /stop in a Telegram chat, or removing the bot from it, stops alerts there.
Legal basis: for members and the chats they connect, performance of a contract (Art. 6(1)(b) GDPR); for an address without an account, your consent (Art. 6(1)(a) GDPR), given by confirming and withdrawn by unsubscribing, which takes effect at once.
Custom domains: we store the hostname you attach to a status page, its CNAME target, when it was added and verified, and the DNS monitor that checks its CNAME. Unverified claims expire after seven days. Our status hosting provider serves public snapshots and their images; our certificate provider receives your hostname to issue HTTPS certificates, whose names appear in public certificate transparency logs. Members-only pages require workspace sign-in and have no public summary or badge. Subscriber lists remain Coming soon.
If you visit a status page
A status page is public. Anyone with its address can read it, and its README badge, which shows the page’s name and overall state, appears wherever the builder put it. The page shows its name and logo, a link to the homepage the builder sets, its components with their state and daily uptime, and incidents with the updates the builder published. A new page starts with its app’s address as that homepage, which is often an address one of its monitors checks. Otherwise it shows no monitor’s address, settings or headers, and no unpublished update. What it says is the builder’s.
Staygreen records nothing about you when you read one: you need no account, we set no cookie of ours, and our database holds no IP address. Our hosting provider handles the request and, like any web host, sees your IP address. Like every page on Staygreen’s own site, a status page loads Clerk’s scripts from Clerk, which therefore sees your IP address too and can set the cookies described below. Legal basis: our legitimate interest (Art. 6(1)(f) GDPR) in serving the page and keeping the site secure.
The one-time scan and embedded widget
The public scan needs no account. It sends the app address to our checker and reads public responses, registry expiry information and, only when supplied, the service identified by your restricted Stripe or Supabase publishable key. Keys and results are used for that response only, never stored or logged. We keep short-lived abuse counters under a keyed hash of the caller's IP address, or its authenticated credential identity, with a shared global counter. They expire after at most ten minutes and are removed during subsequent admissions. Raw IP addresses are not stored in our database. The websites, registries and services contacted see the checker's request. Our legitimate interest in providing the requested check and preventing abuse is the legal basis.
The embedded widget reads only a public status summary. It sends no cookies or referrer, performs no fingerprinting and uses no analytics. Dismissing a banner stores its published update id in localStorage on the host app's origin, until another dismissal replaces it or you clear that storage. Only published updates appear. Members-only pages have no public widget, summary or badge.
Cookies and browser storage
Staygreen uses essential cookies only. There is no cookie banner because there is nothing to consent to: no advertising, analytics or cross-site tracking cookies.
sg-themeremembers Light, Dark or System when you choose a theme in Settings. It holds only that word, lasts 365 days and is SameSite=Lax. It is a first-party preference cookie with no identifier in it, and needs no consent banner.- Clerk’s cookies keep you signed in and protect sign-in. Clerk’s scripts, which include its protection against automated sign-ups, run on every page of Staygreen’s own site, including status pages served at our own site address, so some of its cookies are set before you ever sign in: on our address, one that records whether this browser is signed in, and on Clerk’s own address, security cookies of the network in front of it, such as Cloudflare’s
__cf_bm. Staygreen’s own code reads one,__client_uat, on the public pages, only to choose whether the header’s button says Sign in or Open dashboard; both open the same page. - Session storage. In the dashboard, the app you chose in the app switcher is kept in this tab’s session storage, as your workspace’s and the app’s identifiers, so a reload keeps it. A new tab starts on all apps, and it goes when the tab closes.
Staygreen runs no analytics: no script that records how its pages are used is loaded.
Who else processes it
When you connect Slack or Discord, that service receives the channel identifier and alert messages, including masked evidence and links. A signed webhook sends the same information to the endpoint you choose, under your arrangement with its operator.
- Clerk: accounts, workspaces, sign-in, its emails and the scripts every page loads, and subscription billing.
- Supabase: the database, holding everything a workspace holds, listed above.
- Our hosting provider: serves Staygreen’s site, the dashboard and status pages, and runs the tests and suggested checks you start from the dashboard.
- The servers that run checks, in Toronto and San Francisco, and the provider we rent them from: they read each monitor’s settings and its encrypted headers, open the headers only to send the request, and write the results described above.
- Anthropic: when Staygreen suggests an app’s checks, its model may be asked to pick the app’s brand colour among those found on the app’s site and to propose checks for its health routes. It receives the app’s host, those colours and at most two of the app’s public health responses, with anything that looks like a secret masked; nothing about you or your workspace.
- Postmark: sends alert email, and the email that asks an added address to confirm. It receives each recipient’s address and the message: the app’s and monitor’s names, what failed with the masked evidence, and the links. Open and link tracking are off.
- Telegram: delivers alerts to the chats connected to a workspace. It receives the chat’s identifier and each message, and passes us the chat’s name when it is connected and the commands sent to the bot.
- Stripe, through Clerk, if you buy Builder. We never see or store your card details.
Each is a processor acting on our instructions under a data processing agreement. Where any of them processes data outside the European Economic Area, that transfer relies on the European Commission’s Standard Contractual Clauses.
When you connect a coding agent
Clerk handles OAuth sign-in and consent. We verify the selected workspace and current membership on each call and store no OAuth access or refresh tokens. Your agent receives workspace monitoring data and can create monitors, pause them briefly and draft updates if its access allows it. The client you choose processes that data under its own terms.
API tokens have a name and scope, a public identifier and a keyed hash; the secret value is shown once and is never stored. Revocation leaves a tombstone. Writes keep an activity record with the client name and resource identifier, plus a retry receipt with a keyed input fingerprint and the result. A provisioning receipt can include encrypted copies of the new heartbeat credentials, so the creating request can recover a lost reply; existing heartbeat credentials are not exposed to agents. Call logs record method, tool, result code, duration, client and a workspace or hashed actor identifier when known, including refused calls. They contain no request arguments, tokens, IP addresses or response bodies. Admission counters use keyed identifiers.
These records and the hourly and daily response-time summaries currently have no scheduled deletion. Workspace records are deleted with the workspace; counters and unattributed call logs are removed on request. Revoking a token stops its use but does not erase its activity.
How long we keep it
- Your account is kept until it is deleted: by you, where Clerk’s account settings offer it, or by us on request.
- What a workspace holds is kept until a member deletes it. Deleting a monitor deletes its headers, check results, incidents and updates at once. Deleting an app deletes its monitors, its status page and its logo. Deleting a status page deletes its images, and its address stops answering.
- Check results: the 5-minute summaries, daily totals and changes of state are kept as long as their monitor. A monitor keeps its last 20 failed checks, and an older one is deleted when a newer one arrives.
- Test counts, and counts of test alerts and confirmation emails: one per member and one per workspace, started again with each window, kept while the workspace exists.
- Alert receipts are kept as long as their incident, and a test’s as long as the workspace. A removed channel’s receipts stay in the list without it.
- An added address, chat or webhook channel is kept until a member removes it, unsubscribed, stopped or never confirmed included. Removing it deletes it at once.
Being straight with you about deletion: nothing in Staygreen deletes on a schedule yet, so check results stay until their monitor is deleted. Deleting a whole workspace isn’t built either, and deleting your account or your organization in Clerk doesn’t delete what the workspace holds from our database: its monitors stay stored, its status pages stay public, and your Clerk identifier stays beside the incident updates you wrote and the alerts sent to you. In the meantime we delete on request, promptly, and you should ask (below).
Your rights
Under the GDPR you may ask us to:
- tell you what we hold about you, and give you a copy (Art. 15);
- correct anything inaccurate (Art. 16);
- delete it (Art. 17);
- restrict what we do with it (Art. 18);
- hand it over in a portable form (Art. 20);
- object to processing based on legitimate interest (Art. 21).
There is no charge, and we answer within one month. Write to us at the address above or at contact@staygreen.io. If you have only read status pages, we hold nothing about you to give back.
You also have the right to complain to a supervisory authority. Ours is the President of the Personal Data Protection Office (Prezes Urzędu Ochrony Danych Osobowych), ul. Stawki 2, 00-193 Warszawa, Poland, https://uodo.gov.pl.
Security
Slack bot tokens, Discord webhook URLs and signed-webhook URLs and signing secrets are encrypted before storage, never shown after saving, and deleted when their channel is removed. A Slack installation keeps only a hash of its one-use connection state, bound to the member and workspace, for validation within ten minutes; consumed states are deleted and expired ones are cleaned up when that workspace starts another installation. Signed-webhook receipts retain the masked JSON payload so every retry carries the same event.
Only our servers talk to the database, and no key that could read it is ever sent to a browser. Row-level security is on for every table with no policies, so a leaked public key reads nothing. The servers that run checks connect with database roles of their own, which can call only the functions they need and can’t read a table directly. Header values and heartbeat URLs are encrypted with AES-256-GCM, and every change you make is checked on the server against the workspace that owns it.
Children
Staygreen is a tool for people who build software, and isn’t directed at children under 16.
Changes
If this policy changes, we update the date at the top, and tell workspace admins by email before a material change applies. The terms of service are the other half of this.