SFTP data automation
Keep your enterprise's members in step with your HR system without writing an integration. Your system uploads a CSV file to Kesk's SFTP server, and Kesk invites the people who are new and removes the people who have left.
SFTP suits HR and finance systems that can deliver a scheduled report as a file but cannot call an API. You choose the schedule, and nothing needs to run on Kesk's side between uploads.
Security
- SSH keys only. The server accepts public-key authentication and rejects every password. You register the public key with Kesk, and the private key never leaves your system.
- Supported key types: Ed25519 (
ssh-ed25519), RSA (ssh-rsa), and ECDSA (ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521). - Login lockout. After five failed logins from one IP address, the server rejects further attempts from that address until five minutes after the last failure.
- Idle timeout. A connection with no activity for 60 seconds is closed.
- Tenant isolation. A login sees only its own enterprise's files. Paths
containing
..are refused. - Separate from the API. SFTP does not use your OAuth client or its tokens, and a token cannot log in to SFTP.
SCIM or SFTP
SCIM provisioning and SFTP are two ways to do the same job,
and an enterprise runs one of them or neither — never both. A settings write
that would leave scimEnabled and sftpEnabled both on is rejected with SFTP
and SCIM provisioning cannot both be enabled simultaneously.
Use SCIM when your identity provider pushes changes as they happen. Use SFTP when your HR system exports a roster file on a schedule.
Setup
Setup takes four steps. Involve whoever administers your HR system and your network: the HR system produces the file, and your firewall has to allow the connection out.
Step 1: Enable SFTP
Turn on sftpEnabled in your enterprise's Settings.
Read the record first to get its id:
Then switch SFTP on:
updateSetting requires
enterprise:settings:write. If SCIM is on, pass scimEnabled: false in the
same input. Otherwise the write is rejected. Turning SCIM off stops SCIM
provisioning immediately.
Once SFTP is on, sftpUsername holds the username you log in with. It is
null while SFTP is off.
Step 2: Create and register an SSH key
Generate a key pair on the machine or service that will upload the files.
macOS and Linux:
Windows, in PowerShell with the OpenSSH client installed:
That writes the private key to kesk_sftp and the public key to
kesk_sftp.pub. Register only the public key. It must be a single line in
OpenSSH format, <algorithm> <base64-key> [comment], for example
ssh-ed25519 AAAAC3Nza... kesk-sftp. A PEM or X.509 export is rejected.
Keys are registered with the addEnterpriseSftpKey operation, which takes a
keyName (1 to 255 characters) and the publicKey. It is listed with
enterpriseSftpKeys and removed with deleteEnterpriseSftpKey.
These three operations are not part of the Enterprise API documented here.
As of 2026-09-17 they are served only by the Kesk for Business API that backs
the business portal. The caller must be a signed-in account whose role grants
SETTINGS_VIEW to list keys, or SETTINGS_MANAGE to add or remove them. An
OAuth client token cannot call them. The portal has no screen for SFTP keys yet.
If you have no way to call the operation, contact
[email protected].
A key can belong to only one enterprise. Registering a key that is already registered anywhere on Kesk fails with SSH key is already registered. You can register several keys for one enterprise. To rotate, add the new key, move your uploads to it, then delete the old one.
Step 3: Connect
| Setting | Value |
|---|---|
Host | sftp.kesk.app |
Port | 2222 |
Username | Your enterprise id, as returned in sftpUsername. ent_<id> is also accepted |
Authentication | The private key from step 2 |
The username must match the enterprise that owns the key. A registered key with another enterprise's id is a failed login.
-o IdentitiesOnly=yes makes the client offer only the key you named. Without
it, OpenSSH also tries every key in your SSH agent. Each unregistered key it
tries counts toward the five-failure lockout, so a well-stocked agent can lock
you out before the right key is offered
(backend#908).
Check the server's host key on your first connection, and treat a later change as a failure. Record the fingerprint your client shows the first time, or read it ahead of time with:
If a later connection reports that the host key has changed, do not accept the new key. Ask [email protected] to confirm it first. The server generates a new host key at startup unless one is configured for it (backend#908). A change can therefore be a restart, but it can also be an attack, and you cannot tell the two apart from your side.
Step 4: Find your way around
| Path | You can | Used for |
|---|---|---|
/to_kesk/employees/ | Upload, rename, delete | |
/to_kesk/employees/add/ | Upload, rename, delete | |
/to_kesk/employees/remove/ | Upload, rename, delete | |
/from_kesk/reports/ | Read | |
/from_kesk/trips/, orders/, invoices/ | Read |
You can write, rename and delete files only under /to_kesk/. Everything
under /from_kesk/ is read-only. The folders are fixed: you cannot create or
remove directories. Each uploaded file is limited to 50 MB.
The server does not support setting file attributes. If your client sets timestamps or permissions after an upload (the "preserve timestamps" option in many graphical clients), switch that off. Otherwise the client reports an error for that step, even though the file itself arrived.
One enterprise per key
A username and its keys belong to one enterprise. If you administer several enterprises, enable SFTP on each one and register a separate key for each, since the same key cannot be registered twice. Each enterprise has its own folders and its own roster.
Guides
- Managing employees — the three upload folders, the CSV format, the safety threshold and the reports
- Data exports — what
/from_kesk/is for - HRIS integration — setting up a scheduled upload from an HR system
- FAQ
Reference
Generated reference — every type, field and argument of the Enterprise GraphQL API, built from the live schema. SFTP itself is not GraphQL and is documented in full in this section.