Plutus

Security

You’re handing us read access to your bills. Here’s exactly what that means.

Connecting a cost tool means giving it credentials to the systems that run your company. That deserves a straight description of what happens to them, not a badge. This page is that description. It ends with what we don’t have yet.

Read-only on your cloud

Plutus never changes a resource in your AWS, GCP or Azure account. It reads billing, recommendations and the inventory the savings checks need, such as instances, volumes and load balancers. On GCP it runs BigQuery queries against your billing export, which show up on your own bill. Some non-cloud connections need broader credentials, and the list below names them. Acting on a recommendation stays with your team.

Your credentials are encrypted before they land

Every third-party credential is encrypted with AES-256-GCM before it is written to the database, under a key held outside it. Once saved, no path in the product returns a secret to a browser. The connection screen can tell you a field is set without being able to show you what it is.

Your cost data is yours

It is never sold, and never used to train third-party AI models. Export it as CSV whenever you like, and if you delete your account it is removed rather than retained. That includes the time-series history, not just the login.

Reaching your cloud

AWS is a role you deploy, not a key you paste
Access is a cross-account IAM role in your own account, created from a CloudFormation template or Terraform module. It grants Cost Explorer, Health, and EC2, load balancer, reservation and Savings Plans describe calls, plus read access to one Data Export bucket if you connect one. It has no create, modify, tag or delete permission. You can revoke it from your side at any moment without asking us.
An external ID unique to your account
That role is bound to an external ID derived for your account alone, so the role you deploy cannot be assumed on behalf of anybody else. It is the standard defence against a confused-deputy attack, and not a shared secret across customers.
Outbound requests are checked before they are made
Anywhere the product calls a URL you supplied — a webhook alert destination, for example — the address is validated as a public HTTPS endpoint first, so an internal address cannot be used to make Plutus fetch something on an attacker’s behalf.

What each connection asks for

GCP and Azure
GCP takes a service account key with a custom role: read access to your billing export dataset, permission to run query jobs, and the Recommender reads for idle resources, machine types and committed use. Azure takes a service principal with the Cost Management Reader and Reservations Reader roles.
OpenAI and Anthropic need an admin key
Per-key and per-model usage is only available through each provider’s admin API, so OpenAI takes an Admin API key and Anthropic an Admin key or an Enterprise analytics key. Those keys carry organisation-level access on the provider’s side. Plutus calls the usage and cost endpoints with them.
Connections that need broader credentials
GitHub events take a classic token with repo scope, Salesforce an OAuth grant with API access, Grafana IRM an Editor service account, Twilio a main API key, Confluent an OrganizationAdmin or BillingAdmin key, and Snowflake a username and password for a user you create. OpenRouter and xAI take management keys. Jira, Linear, CircleCI, Databricks, Fireworks, Paperspace and Lambda tokens are not scoped by the provider. Stripe, Datadog, Cloudflare, MongoDB, Hetzner, DigitalOcean, GitLab, Sentry, PagerDuty and HubSpot use read-scoped credentials.

What is stored, and where

Cost rows, not raw bills
Plutus stores cost summarised by service, region, account and usage type, with quantities and the tags you choose. On AWS and Azure that is the one allocation tag key you name. On GCP and Kubernetes it is every label. AI rows carry the provider’s API key ID, never the key.
Hosted in Germany
The application and cost database run on Hetzner in Nuremberg, and the account database on Neon in Frankfurt. The providers that handle your data are listed in the privacy policy.

Signing in

Two-factor on every plan, including the free one
Authenticator app or emailed code, enrolled independently, with one-time recovery codes issued once and stored hashed. Turning a method off requires your current password. Nothing here is reserved for a paid tier.
Trusted devices waive the second factor, never the first
Choosing to remember a browser skips the code for thirty days on that browser only. The password, or the Google or GitHub step, still runs every time. Each device is a separate record you can revoke on its own, and changing your password revokes all of them.
Single sign-on with Google or GitHub
Available on every plan, alongside email and password. Enterprise directory integration via SAML is not shipped today.

Sessions

Sessions end when you say they do
A session lives in a cookie JavaScript cannot read, and is re-checked against the live account on every single request. Change someone’s role, remove them from an organisation, or deactivate them, and their access stops on their next request, not whenever a token would have expired.

Keeping accounts apart

Membership is the source of truth
Access to an account is a membership record with a role attached, not a field on your user. Switching between organisations re-issues your session with that organisation’s role, so permissions in one never leak into another.
Every account route checks membership
Every route that takes an account identifier has to prove the caller belongs to it. A static-analysis rule runs on every pull request and flags any such route added without the check.
Three roles, enforced server-side
Admin, member and viewer. The interface hides what your role cannot do, and the API refuses it independently. The screen is a convenience. The server is the boundary.

What is recorded

An activity log your own admins can read
Who invited whom, who connected a source, who changed a budget. All of it recorded automatically and readable by your administrators, kept for as long as your plan’s retention window. Internal support actions are logged separately and just as completely.

What you can remove

Deletion means deletion
Disconnecting a source deletes its credential and keeps its history. Removing the source purges the cost history that came from it too. Deleting your account cancels any subscription immediately and removes your data across both stores. All three are self-service.
Retention is a number on your plan
Cost and usage history and the activity log are kept for the window your plan includes, from thirty days on the free plan to three years on Enterprise, and purged automatically past it. Events from releases, incidents and CRM sources are kept until you remove that source.

How the code is checked

Secrets cannot reach the main branch
A credential scanner runs on every pull request and blocks the merge outright. It is the one check with no override, on the reasoning that a leaked key is the failure that cannot be walked back after the fact.
Static analysis, dependency and container scanning
Code, infrastructure definitions and workflow files are scanned on every pull request; dependencies and built images are scanned nightly against fresh advisories, so a vulnerability disclosed after a release still surfaces.
The live site is probed, and every release is inventoried
An automated scan runs against the running application weekly, and each release publishes a software bill of materials listing everything inside the image. That record answers “were we exposed to this?” about a component months later.

Where we are on formal certification

Plutus does not hold SOC 2 today. If your procurement process requires it, that is a real answer to have before a trial rather than three weeks into one, and it is why it’s written here rather than left for a questionnaire.

What exists in the meantime is everything above, plus the per-release inventory that a Type II report eventually needs a history of. That history cannot be created retroactively, so it is already being kept. SAML single sign-on and directory-driven provisioning are not part of the product today.

Found something?

Email security@plutus-cloud.com rather than opening a public issue. You’ll get an acknowledgement within three business days and an initial assessment within ten. You’ll also get a straight answer about whether and when it’s being fixed, including “we don’t think this is a vulnerability, and here’s why”. Anything touching tenant isolation, authentication or credential exposure is fixed in days rather than scheduled. We’ll credit you in the release notes if you’d like to be credited, and we’ll work to your disclosure deadline rather than asking you to sit on it indefinitely.

Get started freeSee what it connects to