Feature

Encrypted credential storage
for authenticated scans

Authenticated scanners need credentials. SecPortal stores them with AES-256-GCM authenticated encryption, scopes them to a verified domain inside a workspace, gates access through RBAC, and records every lifecycle event in the activity log.

No credit card required. Free plan available forever.

A credential vault built for authenticated scanning, not a generic password manager

Authenticated scanning is the part of dynamic application security testing that actually reaches the surfaces attackers target. To get there, the scanner needs valid session material: a cookie, a bearer token, an HTTP basic credential, or a form-login flow. Storing those credentials safely is non-trivial. Most teams default to one of three bad options: paste them into chat each time, keep them in a generic password manager that was never designed to be machine-readable from a scanner, or stand up a bespoke vault with its own access model.

SecPortal stores authenticated scan credentials as a first-class object alongside findings, engagements, and verified domains. Each credential is encrypted with AES-256-GCM, scoped to a verified domain in the workspace, gated by RBAC, audited through the same activity log as the rest of the platform, and consumed only at scan execution time. The plaintext lives in memory inside the worker for the duration of one scan and never leaves the server boundary.

How the encryption is built

The cryptographic primitive is AES-256-GCM, an authenticated encryption mode that provides both confidentiality and integrity in a single pass. The implementation lives in a small server-only module and is exercised by the credential APIs, the scan worker, and any other server route that needs to read the secret. The properties below describe what the code actually enforces, not aspirational claims.

AES-256-GCM authenticated encryption

Every credential payload is encrypted with AES-256-GCM. The 12-byte initialisation vector is generated fresh for every record from a cryptographically secure random source, and a 16-byte authentication tag is stored alongside the ciphertext to detect tampering at decryption time.

Versioned ciphertext for safe key rotation

A one-byte key version prefix is written into the ciphertext. Decryption falls back to a configured previous key when the current key cannot decrypt a record, so credential storage stays readable through a key rotation without a migration window.

JSON payload encryption, never plaintext at rest

Credential payloads are serialised, encrypted, and stored as the encrypted byte stream plus its IV and tag. Plaintext is only reconstructed in memory at scan execution time and is never written to logs, scan results, finding evidence, or activity metadata.

Server-only encryption boundary

Encryption and decryption run inside server-side route handlers and the scan worker. The browser never sees the encryption key and never receives the plaintext credential after creation, so a compromised browser session cannot exfiltrate stored secrets.

Tenant isolation enforced by Postgres RLS

The auth_credentials table has row-level security enabled. Every read and write is scoped to the workspace through the user profile, so a workspace can only see and decrypt its own credentials even if a query is constructed without a workspace filter.

Append-only audit through the activity log

Credential creation and revocation log activity events with the credential label, type, and verified domain. The events flow into the same activity feed that records findings, engagements, and team changes, so credential lifecycle is reviewable from one place.

Four credential types, one storage shape

The credential vault holds the four authentication shapes that real applications use. Whatever the type, the payload is encrypted as a JSON document and stored with the same IV plus auth tag layout, so the storage model does not change as the application stack changes.

Cookie

Paste session cookies for applications that authenticate with cookie-based sessions. Useful when the team already holds a logged-in browser session and wants the scanner to inherit it without rerunning the login flow.

Bearer token

Supply a JWT or OAuth bearer token for API-first applications and single-page apps that authenticate through an Authorization header. The token travels in encrypted form and is attached to scanner requests at execution time.

Basic authentication

Username and password for HTTP Basic Authentication, common on legacy admin panels and internal staging environments. The credential pair is encrypted at rest and replayed only against the verified target URL.

Form login

Login URL, username field name, password field name, and credentials for form-based authentication. The scanner performs the login flow at scan time, captures the resulting session, and runs the test suite under that session.

Lifecycle, end to end

A credential moves through five stages from creation to revocation. Each stage is deliberately small so the boundary between encrypted and plaintext is easy to inspect.

  • A workspace member with the manage_credentials permission opens settings and adds a credential against a verified domain. The plaintext credential payload is encrypted server-side and the database row is created.
  • The scan worker pulls a job that references the credential, decrypts the payload in memory, performs the authenticated request flow against the verified target URL, and discards the plaintext when the scan ends.
  • Each scan that uses the credential updates the last_used_at timestamp so the workspace can see which stored credentials are still active and which are dormant.
  • A workspace member opens settings and triggers a test against a stored credential. The platform attempts an authenticated request, reports success or failure, and never returns the plaintext to the browser.
  • A workspace member or owner revokes a credential. The row is deleted, an activity event records the revocation, and any future scan that references the credential fails fast rather than running unauthenticated.

Access control: who can hold the keys

Storing a credential safely is only half the problem. The other half is making sure the people who can add, test, and revoke credentials are the right people, and that what they did is reviewable later. SecPortal handles both through team management with RBAC and multi-factor authentication rather than a parallel access model.

  • Owners, admins, and members hold the manage_credentials permission, so most operators on the workspace can add and revoke credentials.
  • Viewers do not hold manage_credentials and cannot create, test, or delete stored credentials, so read-only stakeholders cannot move scanner secrets.
  • Every credential mutation is recorded as an activity event attributed to the acting user, so an audit can trace who added or revoked a credential and when.
  • The browser never sees the plaintext credential payload after creation. List endpoints return only metadata fields (label, credential type, target URL, last used at, created by, created at).
  • Workspace MFA enforcement promotes sessions to AAL2 before the credentials settings tab is reachable, so credential changes inherit the same second-factor requirement as the rest of the workspace.

Bound to a verified domain

A credential without a target is only half a record. SecPortal binds every stored credential to a verified domain in the workspace, which keeps the authorisation surface consistent across credential storage, scan launch, and ongoing monitoring.

  • Every credential references a verified_domains row in the same workspace. A credential cannot be created without a verified domain, so the workspace has already proven control of the target before the secret is stored.
  • The target URL hostname is checked against the verified domain at credential creation. A credential for example.com cannot be aimed at attacker.com, even by a malicious operator with manage_credentials.
  • The same verified domain is the authorisation surface for external, authenticated, and continuous scans. Credential storage and scan authorisation share the verification record.
  • Deleting a verified domain cascades through the credential rows tied to it, so a domain decommission also removes the credentials that were valid only against that domain.

Plan gating and rate limits

Authenticated scanning is the buyer-evaluation surface for stored credentials. The controls below run at the API layer, not as a UI suggestion, so a scripted client gets the same answer as the dashboard.

  • Authenticated scanning is a plan-gated feature. Workspaces on plans without authenticated scanning cannot create stored credentials and the API rejects credential creation with a clear error.
  • Plan limits on verified domains apply when a credential creation request would auto-create a new verified domain. The credential cannot exist without a verified domain in the workspace.
  • Rate limiting protects the credential creation endpoint at ten creations per fifteen minutes per user, so a stolen session cannot bulk-stuff a workspace with credentials.

Questions an enterprise reviewer should be able to answer in five minutes

Procurement and security architecture reviews routinely ask the same questions about any tool that holds credentials. The vault is built so that the answers are visible from the dashboard or from the activity log rather than reconstructed from inference.

  • Who can create scanner credentials in this workspace, and which team roles hold the manage_credentials permission today?
  • Which credentials are currently stored, against which verified domains, and when was each one last used by the scanner?
  • When was credential X added, who added it, and was it tested before the first scan ran against the target?
  • When was credential Y revoked, who revoked it, and were any scans queued or running at the time of revocation?
  • Has the platform encryption key been rotated, and which credentials have been re-encrypted under the current version against the previous version?
  • Are credential payloads ever returned to the browser or written to scan output, and what is the boundary that prevents that?

Where credential storage fits in the rest of the platform

Encrypted credential storage is an enabler, not a standalone product. It lets authenticated scanning run against the surfaces that matter, lets credential handover for pentests happen without pasting secrets into chat, and lets internal teams operate the kind of repeatable authenticated test cycle described in security testing program management.

Scanner output context lives in scanner authentication failure modes, which explains the failure shapes that show up when a stored credential expires, is rotated by the application team, or no longer matches the login flow. When a stored credential goes stale, the test endpoint surfaces the failure before the scheduled scan run does.

For the audit framing of credential lifecycle as evidence, see the audit evidence half-life research: a credential record carries a meaningful half-life when its lifecycle events are linked back to the scans, findings, and engagements they enabled, rather than sitting alone as a row in a vault.

Credentials and engagement files belong in different places. Scanner output, signed SOWs, attestation letters, and reproduction screenshots go on the engagement record through document management; secrets that authenticate against a target stay in the credential vault. Two access models, two storage shapes, one shared workspace tenant.

The source-control side of authenticated testing has its own storage shape too. OAuth access tokens for code scanning live in repository connections under the same AES-256-GCM scheme as the credential vault, scoped to the workspace, gated by RBAC, and recorded in the activity log on every connect, configure, and disconnect event.

Stop sharing scanner credentials in chat

Add a credential once. The scanner reads it on demand. The team never sees the plaintext.

No credit card required. Free plan available forever.