Recorded Login
Recorded login allows a scan to run using an authenticated session with your app. This simulates the behaviour of an attacker setting up an account before performing reconnaissance. See Recorded Login for detailed setup instructions.
Recorded Login Secrets
When used with internal scanning it is usually desirable to keep credentials within the user’s infrastructure. For example, account passwords, API keys, and one-time-password secrets are stored in a secret store in the user’s infrastructure. The recorded login file is modified to tell the scanner where the secrets are stored. At run time the secrets are read from the secret store and injected into the recorded login file.
For TOTP-based MFA you supply an otpauth_url seed and the scanner generates valid one-time codes during the login replay.
Supported Secret Stores
- Kubernetes Secrets
- Hashicorp Vault
Contact sales if you have other requirements.
Setup Recorded Login
When making the recording, login to the application as you normally would (i.e. enter real passwords, API keys and TOTP codes).
When completed, the recorded login (.trail) file will contain the credentials you entered. These need to be replaced with instructions on how to extract the same credentials from your chosen secret store.
The process is different for TOTP codes and other credentials.
Once the credentials have been removed from the recorded login file it can be uploaded in the Detectify UI.
Standard Credentials
Locate the section in your login file (.trail) where the credential is stored and replace it with the secret reference for your chosen secret store.
This will be in the commands section of the recorded login file.
Recorded action:
{
"type": "UserAction",
"version": "1.0",
"command": "input",
"selectors": [
["css=body > form > input[type=\"text\"]:nth-child(1)"]
],
"values": [
"my-secret-password"
]
}Replace with:
{
"type": "UserAction",
"version": "1.0",
"command": "input",
"selectors": [
["css=#id-of-password-input"]
],
"values": [
"secret={backend=hashicorp_vault, path=recorded-login/credentials, key=password}"
]
}TOTP/MFA Codes
For TOTP codes there are two steps:
- Add a new
setLocalMFAWithVaultcommand to the recorded login file. This tells the scanner where the TOTP secret is stored. - Replace the command where the TOTP code was entered with a
multiFactorAuthSingleField(ormultiFactorAuthSplitFields) command. This tells the scanner to generate a fresh code at replay time.
Recorded action:
{
"type": "UserAction",
"version": "1.0",
"command": "input",
"selectors": [
["css=#id-of-mfa-input"]
],
"values": [
"123456"
]
}Replace with:
{
"type": "UserAction",
"version": "1.0",
"command": "setLocalMFAWithVault",
"values": [
"secret={backend=hashicorp_vault, path=recorded-login/mfa, key=otpauth_url}"
]
},
{
"type": "ExternalInput",
"version": "2.0",
"command": "multiFactorAuthSingleField",
"selectors": [
["css=#id-of-mfa-input"]
],
"values": []
}The setLocalMFAWithVault command must appear before the multiFactorAuthSingleField or multiFactorAuthSplitFields command in the recording file.
In some applications the TOTP code is entered one digit per field. In this case there will be
multiple input commands in the recorded login file. Replace them all with a single multiFactorAuthSplitFields
command listing each field’s selector. See Recorded Login for a detailed example.
Secret Reference Syntax
When providing the location of a secret in the recorded login file, use the following syntax:
secret={backend=<backend>, <backend_specific_args>}The supported backends are:
| Backend | Value |
|---|---|
| Kubernetes Secrets | kubernetes |
| HashiCorp Vault | hashicorp_vault |
Kubernetes Secret Store Arguments
| Argument | Required | Description |
|---|---|---|
name | Yes | The name of the Kubernetes Secret (e.g., recorded-login-password) |
key | Yes | The key within the Secret’s data map (e.g., password) |
namespace | No | The namespace the Secret is in. Defaults to the scanner namespace. |
Example Secret:
apiVersion: v1
kind: Secret
metadata:
name: recorded-login-password
namespace: scanner
stringData:
username: admin
password: t0p-SecretReference in the recording file:
"values": ["secret={backend=kubernetes, name=recorded-login-password, key=password}"]Hashicorp Vault Store Arguments
| Argument | Required | Description |
|---|---|---|
path | Yes | Path to the secret within the KV mount (e.g., recorded-login/credentials) |
key | Yes | The key within the secret’s data map (e.g., password) |
mount | No | KV engine mount point. Defaults to the globally configured mount (typically secret). |
How path, mount and key map to the Vault location
Given a secret reference:
secret={backend=hashicorp_vault, mount=secret, path=recorded-login/credentials, key=password}The scanner constructs the Vault API read path based on the KV engine version configured in the Helm chart (hashicorp_vault.kvVersion):
| KV Version | API path | Notes |
|---|---|---|
| v2 (default) | secret/data/recorded-login/credentials | /data/ is inserted automatically by the Vault SDK |
| v1 | secret/recorded-login/credentials | Path is used directly |
In both cases, key (password) selects a single field from the secret’s data map.
You provide only the logical path — do not include /data/ in the path argument.
Writing the secret to Vault (KV v2):
vault kv put secret/recorded-login/credentials \
username="testuser@example.com" \
password="s3cret"Reference in the recording file:
"values": ["secret={backend=hashicorp_vault, path=recorded-login/credentials, key=password}"]If mount is omitted, it defaults to the value of hashicorp_vault.kvMount in your Helm values (default: secret).
Storing TOTP Secrets
Regardless of the secret store, TOTP secrets must be stored as an otpauth URL:
otpauth://totp/Example?secret=JBSWY3DPEHPK3PXP&digits=6Configuring Secret Stores
Kubernetes
Access
By default, the scanner has access to secrets in the Kubernetes cluster it is deployed in. No additional configuration is required.
Configuration
The following environment variable can be set in the scanner-worker-config ConfigMap:
| Variable | Description | Example |
|---|---|---|
KUBERNETES_SECRET_NAMESPACE | Override the default namespace used when namespace is not specified in the secret reference | scanner |
Managing Secrets
The scan scheduler API can be used to create and manage Kubernetes Secrets in the scanner namespace. See Scanner API for details.
Hashicorp Vault
Access
To enable HashiCorp Vault as a secret backend, set HASHICORP_VAULT_ENABLED to true in the scanner-worker-config ConfigMap.
The scan-worker authenticates to Vault using its Kubernetes ServiceAccount JWT via the Kubernetes auth method . See HashiCorp Vault Integration for full setup instructions including policy and role configuration.
Configuration
The following environment variables can be set in the scanner-worker-config ConfigMap:
| Variable | Required | Description | Example |
|---|---|---|---|
HASHICORP_VAULT_ENABLED | Yes | Enable the HashiCorp Vault backend | true |
HASHICORP_VAULT_ADDR | Yes | Network address of the Vault server | http://vault:8200 |
HASHICORP_VAULT_ROLE | Yes | Kubernetes auth role name | scanner |
HASHICORP_VAULT_AUTH_MOUNT | No | Auth method mount path (default: kubernetes) | kubernetes |
HASHICORP_VAULT_KV_VERSION | No | KV engine version (default: 2) | 2 |
HASHICORP_VAULT_KV_MOUNT | No | KV engine mount path (default: secret) | secret |
HASHICORP_VAULT_CACERT | No | Path to CA certificate file for TLS verification | /etc/vault/ca.crt |
HASHICORP_VAULT_NAMESPACE | No | Vault Enterprise namespace | my-namespace |