Reference
Security & privacy
Frost has no backend. The only network traffic it makes is to AWS, and the only place your token is written is your own disk.
What Frost talks to
Frost makes network calls to exactly three places:
- AWS — the SSO OIDC endpoints for signing in, the SSO endpoints for listing accounts and roles, and EC2/EKS for the cluster scan, all in the region you configured.
- Your access portal — the sign-in page itself, which is an AWS URL or your identity provider's, loaded in the login window or handed to your browser.
- The update service — on macOS and Windows, update.electronjs.org, to find out whether a newer release exists. Platforms →
There is no Frost server. No analytics, no telemetry, no crash reporting, no usage statistics — nothing about your identity, your accounts or your usage is transmitted anywhere.
What Frost stores, and where
| What | Where | Sensitivity |
|---|---|---|
| SSO access token and expiry | Frost's config file (encrypted), and ~/.aws/sso/cache/ |
High — grants every account and permission set you can reach, until it expires |
| OAuth client id and secret | Frost's config file (the secret encrypted) | High — with a device code, could be redeemed for a token |
| Start URL and region | Frost's config file | Low |
| Accounts, permission sets, profile names, clusters | Frost's config file, run history, log files | Medium — an inventory of your organisation's AWS estate |
| Generated profiles | ~/.aws/config |
Low — no credentials, only pointers |
| Cluster endpoints and CA data | ~/.kube/config |
Low — public certificate data |
Exact paths per platform are in files & locations.
Credentials at rest
The two values worth stealing — the SSO access token and the OAuth client secret — are encrypted before they are written to Frost's configuration file, using the operating system's own credential store:
| Platform | Backed by |
|---|---|
| macOS | Keychain |
| Windows | DPAPI |
| Linux | libsecret or kwallet, through your desktop's keyring |
A copied configuration file is therefore not enough on its own: a backup, a synced home directory or another machine's copy will not decrypt. Values written by an earlier version are recognisable as plaintext, read as they are, and re-written encrypted the next time they change — there is no migration step to run.
Two cases are handled deliberately:
- No keyring available — a headless or keyring-less Linux box has nowhere to put a key. Frost stores the value as earlier versions did and logs a warning once, rather than refusing to sign you in.
- A value that will not decrypt — a copied profile directory, a reset keychain, a different machine. Frost treats it as "no credential" and sends you through a fresh sign-in, instead of failing several steps later with a confusing AWS error.
The token cache under ~/.aws/sso/cache/ is
not encrypted. It is the AWS CLI's own file format and
the CLI has to be able to read it, which is the entire point of Frost
writing it. It is 0600, so it is protected from other
accounts on the machine but not from a backup of your home directory.
File permissions
Frost's configuration file and its log files are written with
owner-only permissions (0600), so on a
shared machine another logged-in user cannot read your token or the
account inventory. The permission is applied as the file is written, so
it cannot be widened by your umask, and files left more permissive by
older versions are corrected on the next write.
The file holding the SSO token — Frost's own configuration file — and the
token cache under ~/.aws/sso/cache/ are always written
0600, whatever mode they had before. That is deliberate:
versions up to v0.2.16 created the cache file 0644, and
carrying that forward would leave the token readable by every other
account on the machine.
~/.aws/config and ~/.kube/config are treated
differently, because they are yours — shared with the AWS CLI and
kubectl, and holding entries you wrote. Frost keeps whatever
permissions you gave them, and only picks 0600 when it has
to create the file from nothing. A file that is a symlink stays a
symlink.
| File | Mode |
|---|---|
Frost's config.json | 0600, always |
| Log files | 0600, always |
~/.aws/sso/cache/<hash>.json | 0600, always |
~/.aws/config | Yours, preserved; 0600 if Frost creates it |
~/.kube/config | Yours, preserved; 0600 if Frost creates it |
Every one of these writes is atomic — the contents are flushed to disk before the old version is replaced — so an interrupted refresh, or a machine losing power mid-write, cannot leave a half-written file behind. How the config file is written →
What is deliberately never logged
Logs are written at debug level, which is verbose on purpose — a failed sign-in is diagnosable poll by poll. Three things are excluded on purpose:
- The access token.
- The OAuth client secret.
- The device code, user code and verification URL from the sign-in. Anything holding those alongside the client credentials could redeem a token of its own for as long as the code lives, so the sign-in response is never logged — only its lifetime and polling interval are.
Account names, account ids, permission set names and cluster names are logged, because they are what makes a run readable. Bear that in mind before pasting a log into a public issue.
The token's blast radius
The SSO access token Frost holds is the same one aws sso login
would put on your disk. It is good for every account and permission set
your Identity Center user can reach, and it expires on its own — typically
after about eight hours. Frost does not extend that lifetime; it simply
replaces the token when it expires.
To revoke access, sign out in the AWS access portal or have your administrator remove your assignments; the token stops working. Deleting Frost's configuration file removes the local copy, and quitting Frost stops it refreshing.
The two windows
Sign-in happens on the AWS access portal page. Frost's login window loads that page with Node integration disabled, and Frost never sees your password — only the token AWS issues at the end.
The window injects one small script into the page, to draw the "touch your security key" notice that Electron itself does not provide. That script talks back to Frost over the page's console, a channel a hostile page could imitate — so nothing security relevant hangs off it. At most it picks a window title and asks for your attention. Signing in →
The app window — the one with your settings and status in it — runs with
no access to the system it sits on. It gets no Node, no filesystem and no
network of its own: a content security policy blocks every outbound
request, external script and eval, and the only thing the
page can reach is a fixed list of named operations (read state, save
settings, trigger a refresh, clear history, and so on). It cannot invoke
anything else, and those operations are in turn accepted only from that
window's own top-level frame — a request from anywhere else, the login
window and the remote pages it renders included, is refused and logged.
That matters because the account names, cluster names and AWS error strings the window displays all come from AWS. Even if one of them ever escaped being escaped, there is no longer a live token and a Node runtime sitting behind the page for it to reach.
Builds and the supply chain
- Open source. Everything Frost does is in the public repository, under Apache 2.0.
- Built in public CI. Release artifacts are built by GitHub Actions from a tagged commit, not from anyone's laptop.
- macOS builds are signed and notarized with an Apple Developer ID. Windows builds are unsigned, which is why SmartScreen warns on first run. Platforms →
- The bundled IAM authenticator is pinned and checksum-verified at build time — a mismatch fails the build. Authenticator →
Reporting a security issue
Please report suspected vulnerabilities through the project's issue tracker. If the report itself would expose users, say so briefly without the details and a private channel can be arranged.