Personal Vaults
EnterprisePer-user private credentials in NetStacks: store, edit, and reveal your own SSH keys, passwords, and secrets with audited reveal and AES-256-GCM encryption.
Overview
A personal vault is per-user private credential storage. Every user manages their own credentials from the My Credentials tab, completely separate from the shared organizational Credential Vault. Personal credentials are private to your account and are never shared with other users.
Personal vaults are designed for credentials that should not be shared with the broader team: an individual engineer's SSH key for lab devices, a device-specific password for equipment under one person's responsibility, or a temporary secret for a troubleshooting session.
- Per-user private storage — only the owning user can list, edit, reveal, or use their personal credentials
- Five credential types: SSH password, SSH key, API token, SNMP community, and generic secret
- Reveal requires an audit reason — revealing a raw secret always records why
- Same AES-256-GCM authenticated encryption used for every credential in NetStacks
- Not organized into folders — personal credentials live alongside, but separate from, the shared folder hierarchy
The shared vault uses credential folders with role-based access so teams can collaborate. The personal vault has no folders and no sharing — it is scoped to a single user by owner_id.
How It Works
Personal credentials are owned by the user who created them. The Controller scopes every personal-credential operation to the authenticated user, so listing, editing, deleting, and revealing only ever touch credentials you own. When you browse the credentials available for a device connection, the Controller returns a combined list of accessible credentials and tags each one with a vault_type of personal or shared so the client can show where it came from.
Like the shared vault, only safe metadata (name, type, username, host, port) ever leaves the Controller. Secrets stay encrypted on the Controller and are only decrypted server-side when used for a connection, or returned to you through the explicit, audited reveal flow described below.
Credential Types
A personal credential has exactly one credential_type from this enumerated set:
| credential_type | Label in UI | Typical use |
|---|---|---|
ssh_password | SSH Password | Username + password SSH login to a device |
ssh_key | SSH Key | Private key (the key material is the secret) |
api_token | API Token | Bearer/API token for a device or controller API |
snmp_community | SNMP | SNMP community string |
generic_secret | Secret | Any other secret value |
Every type stores its secret in a single secret field. SSH-style credentials may also carry an optional username, host,port, and an optional enable_secret (for example, an enable/privileged-mode password).
Reveal & Audit
You never see a personal credential's secret by default — the list view shows only metadata. To see a raw value you use the explicit Reveal action, which requires a reason. The reason is sent with the reveal request and recorded for audit, so every disclosure of a secret is traceable to a user and a stated justification.
Revealing a secret is a deliberate, logged action. Provide a meaningful reason (for example, "migrating credential to password manager"). In the web UI a revealed secret is displayed temporarily and auto-hides after 30 seconds.
Because the Controller can use a personal credential for a connection without ever disclosing it, day-to-day work generally never requires a reveal at all — reveal exists for the occasional case where you genuinely need the raw value.
Encryption
Personal credentials use the same authenticated encryption as every other credential in NetStacks: AES-256-GCM with keys derived using Argon2id. Each encrypted value carries its own randomly generated salt, and AES-256-GCM provides authenticated encryption so tampering is detected on decrypt.
Isolation between users is enforced at the access-control layer through ownership checks — the Controller scopes personal-credential operations to the owning user. Secrets are stored encrypted at rest and only decrypted server-side when needed for a connection or an audited reveal.
The credential-vault crypto is a thin facade over an audited, open-source credential-vault library (AES-256-GCM + Argon2id). See the Credential Vault page for the full encryption model.
Using My Credentials
Open the My Credentials tab
- Open NetStacks and go to your credentials view
- Select the My Credentials tab
- The table lists your personal credentials with their Name, Type, Username, and Created date
- Only you can see this list — the credentials are private to your account
Add a credential
- Click + Add Credential
- Enter a Name (required)
- Choose a Type — SSH Password, SSH Key, API Token, SNMP, or Secret
- Optionally enter a Username
- Enter the Secret (required) — the password, key material, token, or community string
- Optionally add a Description
- Click Create
Use My Credentials for lab device logins, personal SSH keys that should not be shared, or temporary troubleshooting secrets. For credentials the whole team needs, use the shared vault with folder-based access instead.
Edit a credential
- Click Edit on the credential's row
- Update the name, username, or description
- To rotate the secret, type a new value in New Secret; leave it blank to keep the current secret
- Click Save
Reveal a secret
- Click Reveal on the credential's row
- Enter an Audit Reason (required) — this is logged
- Click Reveal Secret
- The value is shown so you can copy it, and auto-hides after 30 seconds
Delete a credential
- Click Delete on the credential's row
- Confirm in the dialog — deletion cannot be undone
- The encrypted credential is permanently removed
Controller API Examples
The NetStacks client manages personal credentials through the Controller API under the /api/credentials/personal path. The examples below use the same endpoints and request bodies the application uses.
List your personal credentials
# Returns metadata only (never secrets)
curl https://controller.example.net/api/credentials/personal \
-H "Authorization: Bearer ${API_TOKEN}"
# Response (items array):
# {
# "items": [
# {
# "id": "pc-uuid-1",
# "name": "Lab Switch SSH Key",
# "description": "Personal key for lab",
# "credential_type": "ssh_key",
# "username": "jsmith",
# "host": null,
# "port": null,
# "has_enable_secret": false,
# "created_at": "2026-01-20T14:30:00Z",
# "updated_at": "2026-01-20T14:30:00Z"
# }
# ]
# }Create a personal credential
The request body matches the personal-credential input: name and secret are required; username, host, port, enable_secret, and description are optional.
{
"name": "My Lab SSH Key",
"credential_type": "ssh_key",
"username": "jsmith",
"host": "lab-sw1.example.net",
"port": 22,
"secret": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----",
"description": "Personal Ed25519 key for lab environment"
}curl -X POST https://controller.example.net/api/credentials/personal \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
--data @personal-credential-input.jsonUpdate a personal credential
All update fields are optional. Omit secret to keep the existing secret; include it to rotate.
# Rotate the secret and update the description
curl -X PUT https://controller.example.net/api/credentials/personal/pc-uuid-1 \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"secret": "-----BEGIN OPENSSH PRIVATE KEY-----\n...rotated...\n-----END OPENSSH PRIVATE KEY-----",
"description": "Rotated 2026-06"
}'Reveal a secret (requires a reason)
# The 'reason' field is REQUIRED and is recorded for audit
curl -X POST https://controller.example.net/api/credentials/personal/pc-uuid-1/reveal \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"reason": "Migrating this key to my password manager"
}'
# Response:
# { "secret": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----" }Delete a personal credential
curl -X DELETE https://controller.example.net/api/credentials/personal/pc-uuid-1 \
-H "Authorization: Bearer ${API_TOKEN}"See which credentials you can use
The accessible-credentials list combines your personal credentials and shared credentials you have access to, tagging each with a vault_type.
curl https://controller.example.net/api/credentials/accessible \
-H "Authorization: Bearer ${API_TOKEN}"
# Response items carry vault_type: "personal" | "shared"
# {
# "items": [
# {
# "id": "pc-uuid-1",
# "name": "Lab Switch SSH Key",
# "credential_type": "ssh_key",
# "username": "jsmith",
# "host": null,
# "port": null,
# "vault_type": "personal"
# },
# {
# "id": "sc-uuid-9",
# "name": "Core Switches",
# "credential_type": "ssh_password",
# "username": "netops",
# "host": null,
# "port": null,
# "vault_type": "shared"
# }
# ]
# }Questions & Answers
- Q: What is a personal vault in NetStacks?
- A: It is per-user private credential storage, managed from the My Credentials tab. Each user can store SSH passwords, SSH keys, API tokens, SNMP communities, and generic secrets that are private to their own account and never shared with other users.
- Q: How does the personal vault differ from the shared vault?
- A: The shared vault uses credential folders with role-based access so teams can share credentials. The personal vault has no folders and no sharing — it is scoped to a single user by
owner_id. Personal and shared credentials both appear in your usable list, each tagged with avault_typeofpersonalorshared. - Q: What credential types can I store?
- A: Five enumerated types:
ssh_password,ssh_key,api_token,snmp_community, andgeneric_secret. - Q: How do I see a personal credential's raw secret?
- A: Use the Reveal action, which requires you to enter a reason. The reveal call sends that reason to the Controller, where it is recorded for audit. In the web UI the revealed value auto-hides after 30 seconds. The API endpoint is
POST /api/credentials/personal/{id}/revealwith a requiredreasonfield. - Q: Can I share a personal credential with another user?
- A: No. Personal credentials are strictly private. If a credential needs to be shared, create it in the shared vault and place it in a folder with the appropriate role-based access.
- Q: How are personal credentials encrypted?
- A: With AES-256-GCM authenticated encryption and Argon2id key derivation — the same scheme used for all credentials in NetStacks. Each encrypted value carries its own random salt. Isolation between users is enforced by ownership checks at the access-control layer.
- Q: Can I rotate a secret without seeing the old one?
- A: Yes. Edit the credential and enter a new value in the New Secret field (or send a
secretin a PUT request). Leaving it blank keeps the current secret. No reveal is required to rotate.
Troubleshooting
My Credentials list is empty
If the My Credentials tab shows no credentials:
- You may not have created any yet — click + Add Credential to add your first
- Confirm you are signed in as the account that owns the credentials — personal credentials are scoped per user
- If the list fails to load, check connectivity to the Controller and that your session is still valid
Create fails
If creating a credential fails:
- Ensure both Name and Secret are filled in — they are required
- Pick a valid type:
ssh_password,ssh_key,api_token,snmp_community, orgeneric_secret
Reveal does not work
If you cannot reveal a secret:
- You must enter an Audit Reason — reveal is blocked until a reason is provided
- The revealed value auto-hides after 30 seconds; reveal again (with a reason) if it disappeared before you copied it
- You can only reveal credentials you own
Credential not available for a connection
If a personal credential does not appear when connecting to a device:
- Confirm the credential type matches the connection (for example, an SSH credential for an SSH session)
- Check the accessible-credentials list and confirm the entry shows
vault_type: "personal" - Confirm you are signed in as the owning user
Related Features
Explore related credential management features:
- Credential Vault — The shared organizational vault and the full AES-256-GCM + Argon2id encryption model
- Credential Folders — Organize shared credentials with folders and role-based access
- SSH Passwords & Keys — Details on SSH password and SSH key credential types
- API Tokens — Store and use API token credentials
- SNMP Credentials — Store SNMP community strings as credentials
- Audit Log — Where reveal actions and their reasons are recorded