How Underrunner handles what you connect
Connecting a tool to your cloud is a real decision. This is exactly what it can do, what it stores, and what stops it.
What it can do by default: read
- A new source needs only read access. For AWS we give you a least-privilege policy listing every action, none of which can change anything. For Snowflake we give you the SQL for a role that reads usage views.
- AWS, Databricks, Snowflake, Google Cloud, Azure and Microsoft 365 need no stored key. You create a role, service user, workload identity pool or federated credential that trusts Underrunner's identity provider, for your workspace's subject and nothing else. To sign in, Underrunner signs a token that lasts at most an hour (five minutes where your cloud swaps it for its own) the way GitHub Actions does. Nothing long-lived is kept, and deleting what you created cuts it off. Where a platform allows a rule open to anyone, Underrunner checks before using it, and once a day after that, that a token for anyone else is refused, and won't use one that isn't. That check shows up in your audit log as one refused sign-in.
- Kubernetes needs no way in. A job in your cluster reports out, so a private API server stays private and no cluster credential is kept here. What it sends is a script in the manifest you apply: names, labels, sizes and usage. Environment variables, secrets, annotations and images never leave the cluster. Removals there are steps sent to a person, since Underrunner can't reach the cluster to do them.
- Removal needs a second, separate credential (for AWS, a second role with its own subject, so a role made for reading can't be used to remove), which you add on purpose per source and can take away at any time. Without it, Underrunner can't change anything in that account. It sends people the exact steps instead.
- Execution starts in dry run. Approved items are checked and rehearsed, and nothing is changed.
What has to be true before anything is removed
- An owner has said it isn't needed, and a head of org has approved it. Software can't do either. An LLM can't either: it can only nudge the ranking and word explanations. You can choose to skip the head of org for small things known to be outside production. That's off by default, and the owner's answer is still required.
- Notice has gone out, and the notice period has passed. Anyone with the link can stop it.
- On the day, it's checked again against current data: it still exists, it's still inside an active scope, it isn't protected by a tag, and it hasn't been used since approval. Any failure cancels the removal and sends it back to people.
- Daily limits cap how many things and how much spend can be removed in a day.
- Production is never removed automatically unless you explicitly turn that on. Buckets, Auto Scaling members, Aurora cluster members and anything with deletion protection always go to a person.
- Backups and final snapshots are taken where the platform allows. The plan shown before approval is the plan that runs, including how to undo it.
Scope
A resource can be inside a scope, outside it, or unknown. Only "inside" can be emailed about or removed. If nobody can be identified as responsible, it stays unknown and is left alone. Scope is checked again just before removal.
Credentials and data
- Credentials are encrypted with AES-256-GCM under a key held outside the database, bound to your workspace, and never returned by the API or shown again.
- Underrunner stores metadata about resources: names, tags, sizes, usage numbers, the records in your DNS zones, the titles of tickets that mention them, and short excerpts of code and documentation that mention them. It doesn't read the contents of your buckets, tables or databases, and the policies we give you don't allow it. The one exception you can choose is a billing report in S3, where you grant access to that bucket alone.
- Outbound connections go only to public addresses, follow no redirects, and have time and size limits.
- Every workspace's data is separated in every query, with the workspace coming from your session and never from the request.
LLMs
- If you connect a key, dossiers about flagged resources (tags, usage figures, DNS names pointing at them, ticket titles, code and doc excerpts) are sent to that provider for analysis. Without a key, explanations come from the rules and nothing is sent.
- Text from tags, code and docs is treated as untrusted. The model's output can't trigger an action, and ownership facts it reads from a page only count if the quote is really on that page.
- You set a monthly budget, and calls stop when it's reached.
- Licenses and seats are about people, so they're never sent to an LLM, and nobody's name is searched for in your code or documents.
- Answer links are long random tokens, stored hashed, limited to the items they were sent about, and expire after 45 days. Opening one does nothing, so mail scanners can't answer for anyone.
- Our shared sender only writes to domains you've proved you own with a DNS record, or you can use your own mail server. Either way, an address that only came from a tag waits until someone adds that person or the domain is known to be yours, because an answer link can say a resource isn't needed.
- All values from clouds, tags and docs are escaped before they reach an email or page.
Infrastructure code
- Anything defined in Terraform or other infrastructure code is never deleted through the provider's API, since the next apply would bring it back. The change goes through the code.
- Opening pull requests needs a separate GitHub or GitLab token, which you add on purpose. Without it, the owner gets the exact change by email. It only ever writes to its own branch, never to a default branch, and a person has to merge it.
- It only proposes a change when exactly one block defines the resource and nothing else refers to it. Anything using count, for_each, a module or prevent_destroy goes to a person instead. Closing the pull request counts as keeping the resource.
Signing in
- Single sign-on works with any OpenID Connect provider, using the authorization code flow with PKCE. Tokens are checked for signature, issuer, audience, expiry and nonce.
- A provider only speaks for domains your workspace has proved it owns through a DNS record, and sign-ins are tied to the browser that started them.
- You can require it, which turns off passwords for your workspace, once it has worked at least once. Without it, two-step sign-in with an authenticator app is available for every account.
Audit log
Every answer, approval, removal, credential change and setting change goes into a hash-chained log for your workspace. Each line commits to the one before it, and the app checks the chain whenever you open the log.