Security model
This page explains how Duskwatch protects your DigitalOcean access: on your iPhone, on our optional alert server and on this website. It covers the App Store and TestFlight versions of the app.
In short
- You sign in on DigitalOcean's own page, and sign-in asks only to view.
- Your sign-in stays in this iPhone's Keychain and never reaches our server.
- Alerts use a separate, read-only permission: our server can look, never touch.
- Pushes carry only IDs. Your iPhone adds the names.
- Every action needs a swipe that names it, and Face ID after it. There are no delete actions.
- Alert data stays in the EU and is deleted within 24 hours of turning alerts off.
Sign-in and permissions
Sign-in in the app
- Sign-in: on DigitalOcean's own page, using OAuth 2.0 with PKCE in the iOS system sign-in sheet. There is no token to paste, and Duskwatch never sees your password.
- View first: Sign-in asks only to view. Actions are a separate permission that you approve on the same DigitalOcean page.
- Revoke: you can revoke either permission on DigitalOcean's side at any time.
Your permissions stay on your iPhone
- Keychain only: the sign-in permission, to view or, once you enable actions, to act, lives in the iOS Keychain, readable only while your iPhone is unlocked, only on this device and never synced to iCloud or restored to another phone.
- Short-lived access: the token the app uses for each request is kept only in memory and renewed when it expires. Each renewal can be used once, and the app never runs two at the same time.
- Never sent: Duskwatch never sends it to its own server, to analytics or to crash reports.
- Widgets and Live Activities: they never read your sign-in; they show what the app wrote.
- App lock: an optional app lock asks for Face ID when you open the app and hides it in the app switcher.
Alerts
How alerts work
- Optional: to watch your team while the app is closed, the alert server asks for its own read-only permission, which you approve on DigitalOcean's page and can revoke there.
- Read-only: it can see status, but it cannot reboot, deploy, change or delete anything.
- Write access refused: the server checks the granted permissions every time it receives or renews one, and rejects and revokes any that can write. On top of that, its DigitalOcean client can only make read (GET) requests, to a fixed list of paths.
- IDs only: Notifications carry only IDs. Your iPhone adds the team and resource names, so our server never sees them.
What the alert server keeps
- The read-only permission, encrypted
- The team's ID, a one-way fingerprint of your account, and your device's push address
- Alert rules and mutes, including a spend budget if set and each iPhone's repeat setting, and the last status of what you watch
- Your alert scope, if you pick resources: their IDs, the IDs of the projects you pick, and the resource IDs DigitalOcean lists in those projects, read hourly
- 30 days of alert history, as IDs, never names, with when an alert was acknowledged
- Alert groups for 30 days, as IDs, times and a count, never a list of names
- While a Live Activity runs, its update token from Apple, for at most 12 hours
What it never keeps
- Your password
- The permission that can change things
- Database passwords or connection strings
- Logs or metric history
- The names of your teams and resources
- Who acknowledged an alert, or who muted a resource
Where alert data lives
Alert data is kept in the EU, in Frankfurt, Germany. Turning alerts off deletes it within 24 hours, and "Delete my alert data" in Settings removes the rest.
The database is encrypted at rest, and the read-only permission is encrypted again with its own key. Connections use TLS. The server logs never contain tokens, IP addresses or names.
Without alerts, what the app reads from your account goes only between your iPhone and DigitalOcean. It has no analytics or tracking SDKs.
Alerts for Kubernetes, load balancers, certificates and firewalls
These alerts need a wider read-only permission: Kubernetes, load balancers (with the VPC scope they depend on), certificates, firewalls and projects, all read-only. DigitalOcean can't add scopes to an existing permission, so if you turned alerts on earlier, DigitalOcean asks you once more to approve a read-only permission. The app arms that step with a swipe. Your alert history, settings and acknowledgements move to the new permission.
The same check applies: any scope that can create, update, delete, administer or read credentials makes the server reject and revoke the whole permission. If you leave a scope unticked on DigitalOcean's page, only those alerts stay off.
Acknowledging, snoozing and the Lock Screen
"I'm on it" and "Snooze 30 min" are Duskwatch state, not changes to DigitalOcean: our server keeps when an alert was acknowledged, never who did it, and a snooze as a 30-minute mute, so both reach every device of the account. They need your iPhone unlocked and no swipe, because they change nothing in your account and can be undone.
After you confirm a redeploy, rollback, restart or power action, a Live Activity can follow it on the Lock Screen. With alerts on, the alert server follows that one operation with the same read-only permission, within its hourly budget. Widgets, Siri and Live Activities never power, deploy or roll back anything: their only button is "I'm on it".
Actions
Every change is confirmed
Every action that changes a resource shows one confirmation sheet that names the action, the resource and the team, with a line on what happens next. Every action is armed by a swipe, never a tap, and the swipe says what it does: "Swipe to reboot web-01". Red marks the actions that interrupt a running service.
After the swipe, Face ID or your passcode runs right before the request, every time, and its prompt names the action again: "Reboot web-01 in acme-prod". Without a passcode on the iPhone, actions are blocked. Duskwatch has no delete actions, and it never asks for delete permissions.
A tap on the track only shows a hint; touching and holding, or the VoiceOver action, also works, and there is no setting to turn the swipe off.
All 13 actions
- Droplets: power on, shut down, power off, reboot, power cycle and take a snapshot.
- App Platform apps: redeploy, optionally with a force rebuild; roll back, then commit or revert the rollback; cancel a deployment; restart an app or one of its components ("Swipe to restart worker in api-prod").
- Managed databases: add your IP to the trusted sources.
Changes inside the app
Changes inside the app use the same swipe, without Face ID: signing out of a team, turning off alerts, deleting your alert data, setting a spend budget, enabling actions, muting a resource ("Swipe to mute web-01 for 8 hours") and saving an alert scope ("Swipe to save alert scope").
Unmuting a resource and going back to "All resources" are a single tap.
This website
Waitlist data on this site
- Every page and the signup form are served over HTTPS. Plain HTTP requests are redirected to HTTPS.
- The key to our email provider stays on the server. It never reaches your browser.
- Our code never logs email addresses, names or IP addresses. Abuse protection uses a salted hash of the IP address, kept in memory for a few minutes.
- The site sets no cookies and loads no advertising or cross-site trackers.
- The signup answers the same way whether or not an address is already on the list, so nobody can use it to check who signed up.
Reporting
Reporting a vulnerability
Report a vulnerability to hello@duskwatch.app.
Please include what you found, the steps to reproduce it, and the app version (Settings > About Duskwatch) or the page address. Test only with your own accounts and data, and never send us a DigitalOcean token, password or screenshot that shows account details.
We reply to every report, keep you informed while we fix it, and credit you if you wish. Please give us a reasonable time to fix a problem before you share it publicly.