Security and privacy
This page introduces the security model of DK Studio: exactly which data the platform captures, where that data goes, how long it is kept and who can reach it. It covers both deployment modes β the hosted studio operated by DK Studio, and an in-house installation on your own infrastructure β because the trust boundary is not the same in the two.
The security model
DK Studio runs in one of two modes, and the trust boundary follows the mode.
| In-house installation | Hosted studio | |
|---|---|---|
| Where the studio runs | On infrastructure you control. | On DK Studio's infrastructure. |
| Where the data lives | On your infrastructure, in your database. | With DK Studio. |
| The trust boundary | Your own network: whoever can reach the studio's port may drive your benches. | Your account and your agent credentials. |
| Who holds the database | You do, along with its backups. | DK Studio does; you reach the data through your account and your role. |
The two modes differ in where the processes run and where the data rests. The credential model is the same in both, and it is described below.
| Identity | Where it lives | How it proves itself | What it can do |
|---|---|---|---|
| User | A browser | A session cookie issued by POST /api/auth/login | Use the web UI. Admin pages additionally require the admin role. |
| Agent | A bench or test rig | A two-credential handshake: an API key over HTTP, an agent secret over the socket | Accept and execute commands, report results, emit device events. |
The agent dials out to the studio, so an agent needs no inbound connectivity and no public address β see Network requirements. That holds in both modes: a hosted studio is dialled by the same agents, over the same outbound connection.
The Socket.IO server accepts a connection from any origin and allows credentials, and in an in-house installation the REST API sits outside the studio's own authentication middleware. Run an in-house install on a network you control, or put an authenticating reverse proxy in front of it that terminates TLS and applies per-route authorisation.
Authentication and secrets
The user session
POST /api/auth/login takes an email and a password; the password is stored as a bcrypt hash in
users.password_hash. On success the platform sets two cookies:
sessionβ a base64-encoded JSON payload carrying{id, email, name, role, exp}, whereexpis seven days out.httpOnly,sameSite: "lax",securewhenNODE_ENVisproduction.session_clientβ the same fields as plain JSON, withoutexp, readable by scripts and used by the UI for role checks.
Treat the session cookie as a bearer secret: it is readable by anyone who holds it, so do not log
it, do not paste it into a bug report, and do not forward it to a third-party site. The server reads
the role and the expiry from it on every request. POST /api/auth/logout clears both cookies.
Single sign-on completes the same way: GET /api/auth/sso establishes the session from the
auth_token and refresh_token it receives, and the browser lands back in the studio with the
same role and the same seven-day expiry as a password login.
Admin authorisation
Admin screens are gated in the page middleware: a session whose role is not admin is redirected to
/dashboard.
| In-house installation | Hosted studio | |
|---|---|---|
| Who enforces the rule | Your deployment, and the proxy in front of it. | DK Studio, for every account on the studio. |
| Who may reach the REST API | Anyone who can reach the studio's port: the API is excluded from the studio's authentication middleware, so it is the network and the proxy that decide. | The accounts your organisation holds on that studio. |
The consequence for an in-house install is concrete: put an authenticating reverse proxy in front of the studio, or keep the studio on a segment only your team can reach. A request that arrives without a valid session is served by the API, so the API's own route table is not an authorisation boundary.
Agent credentials
Agent authentication uses two credentials, sent in the request body or the socket payload β never in a header.
| Credential | Shape | Where it is presented |
|---|---|---|
| Licence code | 40 hexadecimal characters | The body of POST /api/agent/register. One-time use; claims a licence. |
| API key | 32 alphanumeric characters | The body of POST /api/agent/auth. The agent never calls this endpoint itself. |
| Agent secret | 64 hexadecimal characters | The auth request payload of the socket handshake. This is the value the socket compares. |
Where the secrets live
- Licence code β in
agent_licensesrows. Shown once when the licence is created, and readable afterwards only by its owner and by an administrator. - API key and agent secret β in
agentsrows and in the agent'sdata/agent.json. These are secrets of the studio's own database; protect the file and its backups accordingly. In a hosted studio that database belongs to DK Studio, and the copy on the bench is the only one you hold. - Session β in the browser cookie, base64-encoded, with a seven-day expiry.
- Studio licence β in
.studio-license.json, written at setup and read on every start. - Dashboard socket token β the
DASHBOARD_WS_TOKENenvironment variable, or the literaldashboard-token.
Treat the database file, the agent's data/agent.json and any backup of them as secrets: whoever
holds them can impersonate an agent or a user.
Data the platform captures
| Data | Where it is stored | What exactly |
|---|---|---|
| Agent registration | agents | Name, capabilities, workstation, status, API key, agent secret, licence id, registration count, timestamps. |
| Command history | agent_commands | Command type, arguments, status, and a result with stdout, stderr, exitCode and durationMs. |
| Serial metadata | Delivered in a device_event | Port path, manufacturer, serial number, vendor id, product id. |
| System information | The result of get_system_info | Hostname, platform, architecture, CPU count, memory, uptime, load average, network interfaces. |
| User accounts | users | Email, name, role and the bcrypt password hash. |
| Test assets | test_cases, test_suites, test_runs, executions | The case definitions, the suite composition, and the outcome of every execution. |
| Run evidence | reports | Artifacts attached to a run: screenshots, captured logs, and the result of each step. |
What is stored is still worth thinking about. A script that prints a key, a serial number or a
customer identifier puts that text into agent_commands, and it stays there. The system-info snapshot
includes the network interfaces of the bench machine, which can expose addresses you would rather not
publish to everyone holding a session.
Where data goes
| Destination | In-house installation | Hosted studio |
|---|---|---|
| The database | Everything the platform records. It stays where you installed it. | Everything the platform records. It rests with DK Studio, and you reach it through your account. |
| Your bench | Commands, arguments and results, travelling over the agent connection. | The same, over the same outbound connection. |
| Your model provider | Only when you use AI assistance: the requirement text or the failure excerpt you asked about, and the draft that comes back. | The same, and it is the provider you configure on the studio. |
| Anywhere else | Nothing. | Nothing. The platform has no telemetry endpoint and no third-party callback. |
AI assistance is off until you configure a provider, and it only sends the material you asked it to work on. If your requirements cannot leave the lab, keep AI assistance off and use the platform without it β every other capability works without a model.
Retention and deletion
Retention is configurable per table, and a background job prunes rows once they fall outside their window.
- Users, agents and licences β kept while the record is active; a deleted agent, licence or user is removed from the database and cannot be recovered.
- Command history β kept for the configured window, then pruned by the retention job.
- Run evidence and reports β kept for the configured window, and removable on demand through the report API.
- Command history can be deleted individually. Every command record can be removed through the API, by id.
If you need a retention window the platform does not cover, apply it at the database level. Your database remains the last line of defence, and a backup of it is a backup of everything. In a hosted studio the same per-table and per-command deletion applies, and the windows are the ones DK Studio configures for the studio.
Access control
| Role | Can do |
|---|---|
admin | Everything in the UI, including user management and agent/licence administration. |
engineer | Authoring, running and reporting; the pages the role navigation allows. |
viewer | Read-only pages. An unrecognised role falls back to viewer. |
In an in-house installation, one studio serves one organisation: one database, one agent pool, one set of projects. Every signed-in user sees the same agents, the same licences and the same command history, filtered by role rather than by tenant. The effective boundary is the database itself β whoever holds the database credentials holds everything the studio holds.
In a hosted studio, the same role model governs the accounts in your organisation, and the boundary is your account: the studio's data is reachable through the accounts your organisation holds and through the agent credentials that let a bench connect. The database and its backups are DK Studio's, and access to them is not yours to grant. See Deployment modes for how the two modes differ in practice.
Reporting a problem
If you find a security issue, report it through the project's support channel, support@dk.studio β
the address published in the application and on the product site. Please include the version you are
running, what you found, the steps to reproduce it, and whether the issue exposes data belonging to
someone else. Do not test against a studio you do not own.
Every capability is listed on the product coverage page; connection-level problems are covered in Agent offline and Unstable connections.