npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nottana/cli

v0.8.4

Published

Nottana command line interface — sign in and use your zero-knowledge vault from the terminal.

Readme

@nottana/cli

Sign in to your Nottana vault from the terminal. Pull secrets straight into your scripts, your CI and your local environment, without pasting them anywhere.

npm install -g @nottana/cli
nottana login

macOS, Linux and Windows. Requires Node.js 18.17 or newer.

Read the code. This package ships unminified — about 28,000 lines with the comments intact, including the ones explaining why each decision was made. You do not have to take the claims below on trust:

npm pack @nottana/cli
tar -xzf nottana-cli-*.tgz && $EDITOR package/dist/cli.js

The only host it talks to is https://api.nottana.com. There are no telemetry calls and no third-party endpoints.

Nottana is zero-knowledge: your master key is derived and used on your machine only. The server stores encrypted blobs it cannot read, and that does not change when you use the CLI.

Why this exists

Today secrets end up in plaintext on developer machines — a .env file, a config pasted into chat, an API key in shell history. That is normal, and it is the genuinely risky part of the status quo: a plaintext file cannot be un-shared once it leaks.

The CLI exists so none of that has to happen. You pull what you need from your vault at the moment you need it, instead of leaving copies lying around. It is not a new door into your account — it is another device you approve, exactly like adding a phone, with the same access your account already has and the ability to disconnect it whenever you want.

Install

npm install -g @nottana/cli

Requires Node 18.17 or newer.

Updating

npm update -g @nottana/cli

Your session survives an update — the token lives in your OS keystore, not in the package.

Uninstalling

Sign out first. Removing the package deletes the command, not the session: the refresh token stays in your keystore and the machine stays connected to your account until it is revoked.

nottana logout && npm uninstall -g @nottana/cli

If you removed the package before signing out, disconnect that machine from Settings → Security → Connected devices instead.

Sign in

nottana login

The CLI prints a short code and a URL:

  Open:  https://app.nottana.com/activate
  Code:  R96Q-WP5T

  Check that this code matches the one shown in the browser
  before approving. If you did not start this, close the page.

Open that page in a browser where you are already signed in, type the code, and confirm. You will be asked for your password or passkey — approving a device is what lets it read your vault, so it needs more than an open session.

The code is never a link you can click. That is deliberate: the single most common attack on this kind of flow is a stranger sending you a pre-filled approval URL. If a code arrives from anywhere other than your own terminal, it is not yours to approve.

Commands

| Command | What it does | | ------------------------------------ | --------------------------------------------------------------------------------------------- | | nottana login [--label <name>] | Sign in by approving in your browser. --label names this machine in your device list. | | nottana login --store-key | Sign in and keep the vault key, so you can read items. Opt-in — see below. | | nottana unlock | Get a vault key for the session you already have — master password, no browser. | | nottana unlock --replace | Same, but start a fresh window when a key is already stored. | | nottana lock | Remove that stored key, without signing out. forget-key is the older name for it. | | nottana logout | Revoke this session, and destroy any stored key. | | nottana status | Which account this terminal is on, where the token lives, and whether it holds a vault key. | | nottana whoami | Just the account, one line. Exits 1 when nobody is signed in, so it works as a guard. | | nottana list | List every item you can read. | | nottana list --vault "<name>" | List one vault. Filters the output; does not restrict what the key can open. | | nottana get <vault>/<item>/<field> | Print one field to stdout, bare, so $(…) is exact. | | nottana get --id <id> <field> | Pick one item when two share a title in one vault. | | nottana get <item> | List the fields that item has, including your own custom fields. | | nottana run -- <command> | Run something with nottana:// references in its environment resolved. | | nottana inject --in <template> | Fill a template's references in. --out <path> writes it 0600. | | nottana --version | Which build is installed. | | nottana --help | The above, in your terminal. |

Reading your vault

list and get need the vault key on this machine, and by default it is not there. A plain nottana login stores only a session token, so a stolen laptop gets API access to data it cannot decrypt.

nottana login                    # once per machine — approves in your browser
nottana unlock                   # then this, whenever you need to read
nottana unlock --30              # or a 30-minute window
nottana get "Dev/Stripe/password"
nottana lock                     # done reading — locks without signing out

--store-key or unlock?

Both end with a vault key on this machine. They differ in what they cost you, and neither is simply better:

| | login --store-key | unlock | | ------------------------------------- | ------------------- | ------------ | | Browser round trip | yes | no | | Master password typed into a terminal | no | yes | | Needs an existing session | no — it creates one | yes | | Cost when the 12h key expires | full re-approval | one command |

If a key is already stored, unlock tells you when it expires and does nothing — it will not ask for your password when there is nothing to do, and it will not silently swap a 12-hour key for a 30-minute one. unlock --replace starts a fresh window.

The rule: login --store-key keeps your master password out of the terminal, at the cost of a browser approval. unlock does the reverse. Pick whichever cost you would rather pay.

Two cases decide it for you:

  • You sign in with a passkey and do not have your master password to hand. Use --store-key. Your browser can seal the key because your passkey already unlocked it; unlock has nothing to work with.
  • A shared, borrowed, or screen-shared machine. Use --store-key. The password never enters that terminal at all, and the browser approval can happen on your phone.

Whichever you use, your master password never leaves your machine. unlock asks Nottana for the same encrypted blob it already stores — which it cannot read — and unwraps it locally. That is what a browser login does, in a terminal. There is no way to do it any other way: Nottana has never held your master key, so no server can hand one out.

A stored key opens your whole vault — there is no per-vault restriction yet, and --vault filters what is printed rather than what the key can open. It lives in the same OS keystore as the session, in a separate entry, which is why forget-key can remove it without signing you out.

Secret references

nottana://<vault>/<item>/<field> names where a value lives, so the file you commit holds the location and not the secret:

# .env.template — safe in git
STRIPE_KEY=nottana://Dev/stripe/api_key

nottana run --env-file .env.template -- npm start
nottana inject --in .env.template --out .env    # writes 0600

Use {{ nottana://… }} to embed a reference inside a longer string, such as a connection URL; the bare form is read only when it is the whole value or runs to the end of its line.

A reference that cannot be resolved stops the run — nothing is spawned and nothing is written. Passing the literal through would send a string that looks like a secret to a real API, and you would meet the failure later as somebody else's 401.

Secrets reach the child process through its environment, never its arguments: a reference written into the command's own arguments is refused, because argv is readable by every user on the machine via ps and your shell history keeps a copy.

Where the session is stored

nottana login stores a refresh token — never your password — in the most protected place available. nottana login --store-key adds a second, separate entry holding an expiring vault key; without that flag no key material is written to this machine at all.

| Platform | Storage | | -------- | ---------------------------------------------------------------------- | | macOS | Keychain | | Linux | Secret Service (GNOME Keyring / KWallet) | | Windows | A DPAPI-encrypted file, readable only by your Windows user (see below) | | Fallback | A file with 0600 permissions, announced on stderr when used |

On Windows the token is encrypted with DPAPI. It is protected with ProtectedData under the CurrentUser scope and written to a file in %APPDATA%\nottana, so it is unreadable by other Windows accounts and is not inherited by the processes you launch. nottana logout removes it.

Before 0.4.4 this was a plaintext user environment variable, readable by any program running as you. If you are upgrading, your session carries over and the old plaintext copy is deleted the next time the token is written.

It is a DPAPI-encrypted file rather than Windows Credential Manager, so it does not appear in the Credential Manager UI. Credential Manager protects its own blobs with DPAPI too, so this is comparable protection with less manageability — moving to it is tracked separately.

The token is never passed as a command-line argument, because arguments are visible to any other process via ps.

Versioning

The CLI is on npm and everything documented here works. It is pre-1.0, so commands, flags and output can change between minor versions, and a change that invalidates a saved session gets a minor bump rather than a major one until 1.0. Pin the version if a script of yours depends on it, and run nottana --version to see which one you have.

What's new

npm has no release-notes field of its own — the package page shows this README and a list of version numbers, nothing more — so the notes live here. Run nottana --version to see what you are on, and npm update -g @nottana/cli to move.

0.8.4

  • Messages about your session now say WHICH server they are about, which stops a loop that could not be escaped by reading either message.

    Sessions are stored per API origin, so a login against one server and a logout against another are separate things. With NOTTANA_API_URL pointed at a local server, nottana login would find that session and say "Already connected — run nottana logout first", while a bare nottana logout looked at the default origin, found nothing, and said "Not signed in." Each command told you to run the other.

    The hint now carries the origin, so it can be pasted and work: Run \NOTTANA_API_URL=http://localhost:3001 nottana logout` first. And a logout that finds no session names the origin it checked, on stderr — stdout is unchanged, so nottana logout || true` and anything parsing that line still behave exactly as before.

0.8.3

  • Nothing changed in the CLI itself, and there is nothing to do after updating.

    The web app's hybrid encryption envelope is now authenticated (AES-GCM rather than AES-CBC with no MAC). The CLI opens sealed key material by delegating to that same code rather than reimplementing it, so it follows the change automatically — this release only updates the test that pinned the old envelope shape. Key material the CLI receives is a 32-byte key, which has always taken the direct RSA-OAEP path, so no sealed blob changes format.

0.8.2

  • A refused unlock duration now tells you the one that works. Nothing else changed, and there is nothing to do after updating.

    nottana unlock --1440 explained that 12 hours is the maximum and then left you to work out that it means --720. It now ends with For the longest window allowed: nottana unlock --720.

    The ceiling itself is unchanged and is deliberate: a stored key opens your whole vault, so it cannot outlive a working day. Over-long requests are still refused rather than quietly shortened, because someone who typed --1440 believes they have it.

0.8.1

  • Documentation only — no behaviour changed, and nothing to do after updating.

    The comment describing how the Windows session token is stored had stopped matching the code. It now says what that branch actually does: DPAPI (ProtectedData::Protect, CurrentUser scope) writing to a file under %APPDATA%\nottana. A security note that describes an older implementation is worse than none, because it is what someone reads instead of the code.

0.8.0

  • nottana whoami — the account this terminal is on, one line, nothing else.

    status answers eight questions at once, which is right when you are reading it and wrong when a script is. This prints the account and exits 1 when there is nobody to name, so it is usable as a guard:

    nottana whoami >/dev/null || { echo "not signed in"; exit 1; }

    It is deliberately not an alias for status: an alias would print the same paragraph and be worth nothing to the scripts that are the reason it exists. If the server does not report an account it says so and still exits 1, rather than printing a blank line a script could read as an identity.

0.7.0

  • nottana run now says something when it resolves nothing.

    It reads no file on its own — it resolves references already present in the environment. So the natural mistake is a .env full of nottana:// references and no --env-file: nothing is filled in, nothing is said, and your command receives the literal nottana://… string as a value. The failure then turns up somewhere else entirely — an SDK rejecting an API key, a captcha that never loads — with nothing pointing back at how it was started.

    No references resolved. .env contains 3 nottana:// references, but
    nottana run does not read a file on its own.
      Did you mean:  nottana run --env-file .env -- <command>

    It only appears when there is something concrete to point at: a readable env file in the working directory that genuinely contains references. If there is no file, no references, or you passed --env-file yourself, it stays quiet.

    Only the COUNT and the filename are printed, never a value — a reference URI names a vault and an item even though the secret itself is not in the file.

0.6.2

  • A signed-out terminal is no longer sent round in a circle. run, get, list, inject and vaults used to answer a missing vault key with "Run nottana unlock" whether or not you were signed in — and unlock replies "You are not signed in. Run nottana login." unlock cannot work without a session, so that was two commands and no way out.

    Being signed out now says so, and points at the one command that fixes both at once:

    error: not signed in on this machine, so there is no vault key.
           Sign in and store a key in one step:
             nottana login --store-key

    unlock is still offered first when you ARE signed in, since that is the cheap fix for the 12-hour key expiring, and it is still the per-API message that wins when NOTTANA_API_URL is in play — being pointed at the wrong API makes both "sign in" and "unlock" a way to make things worse.

  • The "no OS keychain available" warning no longer tells Windows and macOS users to install a Linux package.

    It ended with "install libsecret (secret-tool) for keychain storage" on every platform, so a Windows box with no powershell on PATH — a stripped image such as Nano Server, or some CI containers — fell back to file storage and was handed advice that cannot work there. The remedy now names the command the CLI actually looked for: powershell on Windows, security on macOS, secret-tool on Linux. A platform we do not probe for gets no remedy line at all, rather than a guess.

    Cosmetic in the sense that nothing behaves differently — but this is the one message whose entire job is to be trusted about where your session token went, which is why it is worth a release.

0.6.1

  • nottana inject now handles a quoted reference: MONGO_URI="nottana://Local Dev 2026/api/MONGO_URI".

    It read to the raw end of the line, so the closing quote became part of the field name (MONGO_URI") and the reference resolved to nothing — while nottana run handled the same file perfectly, because it strips quotes before parsing. Two commands disagreeing about one documented syntax. The quotes are now left in place around the substituted value, so a JSON or YAML template stays valid.

    A reference buried mid-string is still refused, unchanged: nothing can tell where it ends, and {{ nottana://… }} is the form for that.

0.6.0

  • nottana status and nottana login now print the account the terminal is signed in as, above the session id.

    Approval happens in your browser, so a terminal joins whichever account was signed in there. That is how the device flow is meant to work, and it means a terminal can end up on an account you did not intend — previously with nothing on screen to reveal it. The symptom was nottana unlock refusing a master password that was correct: the session belonged to another account, so the key it fetched was that account's and yours could not open it.

  • nottana unlock now names the account when it refuses a password, and points at nottana logout if it is the wrong one.

0.5.1

  • npm page only: clearer README, keywords, and the removal of a repository link that went nowhere. No change to the CLI itself.

0.5.0

  • Windows: the session token is now encrypted with DPAPI, in a file only your Windows user can decrypt.

    Until this version it was stored as a plaintext per-user environment variable in HKCU\Environment, readable by anything running as you and visible in Get-ChildItem Env:. Found by running the keystore verifier on real Windows hardware. macOS (Keychain) and Linux (Secret Service) were never affected.

    If you used 0.4.x on Windows, run nottana logout and sign in again — that clears the old environment variable. The CLI also migrates and deletes it automatically the next time it writes, but signing out is the certain path.

0.4.3

  • Corrected a false claim in the docs: the storage table said Windows used Credential Manager. It did not. The storage itself was fixed in 0.5.0.

0.4.2

First public release. login, logout, status, unlock, lock, vaults, list, get, run and inject, with the vault key opt-in and time-bound.

Disconnecting a machine

Sign a device out from Settings → Security → Connected devices in the web app. That list holds every session, not only terminals, and can be filtered to Command line or searched by the session id nottana status prints. Disconnecting takes effect immediately, and that machine has to be approved again before it can read anything.

Environment

| Variable | Purpose | | ----------------- | ------------------------------------------------------------- | | NOTTANA_API_URL | Override the API base. Defaults to https://api.nottana.com. Must be https, unless the host is localhost or 127.0.0.1 — anything else is refused before the command runs. When it is set, the CLI says so on stderr. |

Common questions

When do I use unlock and when do I use login --store-key? Both leave a vault key on this machine. login --store-key never puts your master password in a terminal, but costs a browser approval every time the key expires. unlock skips the browser but asks for the password. If you sign in with a passkey and do not know your master password, --store-key is your only option. See the table under Reading your vault.

Does unlock send my master password anywhere? No. Nottana returns the encrypted blob it already stores and cannot read, and your password is used locally to unwrap it. The prompt does not echo, and the password is never accepted as a flag — --password is refused, because anything in the arguments is visible to every other user on the machine via ps and is kept in shell history.

Is this risky to hand to a junior engineer? That is the realistic risk, more than any exotic attack — someone pipes a secret into a file and forgets it. nottana run exists for exactly that: it passes the secret straight into the process that needs it, so it never lands in a file or in shell history. The vault key is also opt-in and expires, so the default install holds nothing that can decrypt anything.

Scoping is still not shipped: today a connected device has the same access your account does, so treat approving one as you would handing over your signed-in laptop. Per-vault access needs per-vault keys, because item-to-vault membership exists only inside the ciphertext — the server cannot withhold items by vault even if we asked it to.

So it can read all my passwords? Yes — the same way your browser can when you are signed in. It is your vault, so anything you can see, it can see. That is why approving a device asks for your password or passkey, and why the screen spells out what you are granting before you say yes.

What if someone steals my laptop? Then they have a signed-in laptop, the same as if they took your phone. You can disconnect that machine instantly from any other device, and your vault still locks — it is not sitting there decrypted waiting for them.

Is this really safer than a .env file? A .env file is plaintext forever. It gets copied into backups, pasted into chat, and committed to git by accident — and once it has leaked you cannot un-leak it. A CLI session is encrypted, tied to one machine, and revocable. That last part is the real difference.

Why is there no link to click to approve? Deliberate — see above. A one-click approval link is what makes this kind of sign-in phishable, so we never send one.

Do I need to be a developer to use Nottana? No. If you never open a terminal, ignore this entirely; nothing about your account changes.

Can Nottana read my vault when I use the CLI? No, and that does not change between the web app, the phone app and the terminal. Even when you approve a new machine, your browser seals the key to that machine specifically — we relay a blob we cannot open, and delete it the moment it is collected.

Reporting a security issue

Email [email protected]. Please do not open a public issue.

Licence

MIT — see LICENSE.