Skip to main content

SFTP Integration

SFTP (Secure File Transfer Protocol) is the channel through which QI CTVM makes fund reports available for download. The available models, the column-by-column layout of each file, and downloadable examples are in the DTVM Reports documentation.

For the integration, we recommend libraries and clients that implement the protocol, such as paramiko in Python, the command-line sftp, or any standard SFTP client.

Access provisioning

To request access, contact integracao.dtvm@qitech.com.br. Access is granted first in the Sandbox environment and then in Production.

How authentication works

Access is authenticated with an SSH public key — there is no password. You generate the key pair, keep the private key under your control, and send us only the public key, which we register on your SFTP user.

WhoWhat they provide
YouThe public key (the .pub file), in OpenSSH format
QI CTVMHOSTNAME, PORT (22) and USERNAME, plus the host fingerprint
Never send your private key

No QI Tech team will ever ask for your private key. If someone asks — by e-mail, by ticket, or through any other channel — it is not us. The 1Password sharing described in step 3 is for the public key (sftp_qitech.pub) only.

If the private key has already been sent to anyone or attached anywhere, treat it as compromised: generate a new pair and send us the new public key.

1. Generating the key pair

Generate a pair dedicated to SFTP. Do not reuse the key that signs your JWT tokens: they are credentials for different systems, with different life cycles — rotating one would force rotating the other, and a leak on either side would affect both.

Replace company-name with your company's name — for example, sftp-acme. This text is only a comment inside the key, and it is there to help us identify it.

mkdir -p ~/.ssh && chmod 700 ~/.ssh
ssh-keygen -t ed25519 -C "sftp-company-name" -f ~/.ssh/sftp_qitech
Copy the command from the matching tab

Each tab writes the folder path the way that particular program understands it, so the commands are not interchangeable. If you run the command from one tab in a different program, you get No such file or directory and no key is created — just go back and copy the command from the right tab.

On Windows, if you are not sure which one to use, use PowerShell: it is what Windows Terminal opens by default.

The command asks for a passphrase and generates two files:

FileWhat it is
sftp_qitechPrivate key. Never send it, never share it.
sftp_qitech.pubPublic key. This is the one you must send us.

About the passphrase:

  • Automated integration (a service of yours downloading the reports): leave it empty, pressing Enter at both prompts, and protect the private key wherever it is stored, in a secrets manager with restricted access. A passphrase that has to be available to the process at run time adds no real protection.
  • Use by a person: set a passphrase.

ssh-keygen already creates the private key with permissions restricted to your user. If you copy the file to another machine, restore the permissions — SSH clients refuse private keys that are readable by other users:

chmod 600 ~/.ssh/sftp_qitech

2. Checking the public key format

The content of the .pub file is a single line, starting with the key type and ending with the comment:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE1wA3uBEFYG+Yi7zIw7/YUJJ4fBB0MUZsvUVaqyyv6M sftp-acme

Check the file before sending it to us:

ssh-keygen -lf ~/.ssh/sftp_qitech.pub

The expected response is the key fingerprint, in the format 256 SHA256:... sftp-acme (ED25519). If the command answers is not a public key file, the file is corrupted or is not an OpenSSH public key.

If your key is in PEM/X.509 format

A key that starts with -----BEGIN PUBLIC KEY----- is in PEM/X.509 format, the OpenSSL standard. That format cannot be registered on the SFTP: the server expects the OpenSSH format, on a single line.

If that key is already dedicated to SFTP, you do not need to generate another one — just convert it:

  • You still have the matching private key. Works for any key type:

    ssh-keygen -y -f path/to/private_key
  • You only have the public key in PEM. Works for RSA keys:

    ssh-keygen -i -m PKCS8 -f path/to/public_key.pem

Both commands print the key in OpenSSH format to standard output. The conversion does not preserve the original comment; if you want, append sftp-company-name to the end of the line.

3. Sending the public key

Send the public key through 1Password, sharing the item with the integration team. This is the channel we use to receive keys: it preserves the content exactly as you generated it and keeps the origin of the delivery verifiable — anyone able to replace your public key along the way would gain access to your SFTP directory.

  1. In 1Password, create an item and paste the content of the sftp_qitech.pub file into it as plain text, on a single line, with no line breaks.
  2. Add the key fingerprint — the output of the ssh-keygen -lf from the previous step. We compare it with the fingerprint of the key we received and confirm it was not altered along the way.
  3. Share the item with the integration team and let us know at integracao.dtvm@qitech.com.br that the item has been shared.
Do not attach the key in .docx or .pdf

The automatic formatting of those programs replaces characters (a + with an em dash, straight quotes with typographic ones) and inserts line breaks. Any of those changes invalidates the key, and the error only shows up at connection time.

Once the public key is registered, we confirm the release and send you the HOSTNAME, the USERNAME, and the host fingerprint.

4. Connecting to the SFTP

Check the host key on the first connection

On the first connection, your client will ask whether you trust the server. Do not accept it without checking: compare the fingerprint shown with the one the integration team sent. That comparison is what prevents another server from impersonating ours.

ssh-keyscan -t ed25519 <hostname> > qitech_host_key
ssh-keygen -lf qitech_host_key # compare with the fingerprint sent by QI CTVM
cat qitech_host_key >> ~/.ssh/known_hosts

Once checked, known_hosts becomes the client's reference, and connections presenting a different host key are refused automatically.

Connection credentials

CredentialSource
HOSTNAMEServer address, provided by QI CTVM
PORT22
USERNAMEUser, provided by QI CTVM
Private keyThe sftp_qitech file you generated
Warning

These credentials provide direct access to your fund's reports and should not be shared.

Code example

import paramiko

HOSTNAME = "sftp.example.com" # provided by QI CTVM
PORT = 22
USERNAME = "username" # provided by QI CTVM
PRIVATE_KEY = "/path/to/sftp_qitech" # the private key you generated
KNOWN_HOSTS = "/path/to/known_hosts" # with the QI CTVM host key already checked

client = paramiko.SSHClient()
client.load_host_keys(KNOWN_HOSTS)

# Refuses the connection if the host key is not the expected one.
# Do not use AutoAddPolicy: it accepts any server with no verification.
client.set_missing_host_key_policy(paramiko.RejectPolicy())

client.connect(
hostname=HOSTNAME,
port=PORT,
username=USERNAME,
key_filename=PRIVATE_KEY, # paramiko identifies the key type from the file
look_for_keys=False,
allow_agent=False,
timeout=30,
)

try:
with client.open_sftp() as sftp:
# Lists the available files
for name in sftp.listdir("/"):
print(name)

# Downloads a file
sftp.get("remote/path/file.csv", "local/path/file.csv")
finally:
client.close()

5. Downloading the files

Files are named from the fund short name, the report model and the reference date in YYYY-MM-DD format:

  • example_name_assets_wallet_composition_2026-07-29.csv

The available models, the column-by-column layout of each file, and downloadable examples are in the DTVM Reports documentation.

Information

The SFTP service provided is exclusively for downloading files; upload is not permitted.

Key rotation and revocation

To replace the key, generate a new pair and send us the new public key through 1Password, following steps 1 to 3. We register the new key and let you know when the previous one has been removed, so the switch happens with no downtime window.

If you suspect the private key has been compromised, notify the integration team at the same contact: we revoke the old key's access immediately, before registering the new one.