How to Encrypt Files to Alli SFTP
Alli SFTP supports PGP encrypted files, but an SFTP user might have Receives Encrypted Files turned on. This is a technical guide that covers the SFTP user setup in Alli itself as well as how to retrieve Alli SFTP’s public key and use it encrypt files with with gpg, an open-source implementation of the PGP specification.
Set up an SFTP User to Receive Encrypted Files
Add a new SFTP user and check the Receives Encrypted Files.
How-to set up a new Alli SFTP (for instructions on how to set it up)
![](../../__attachments/2998009905/Screen%20Shot%202023-09-12%20at%2006.13.35.png?inst-v=9d2044ed-f5d2-41ad-960f-0e53811769aa)
Encrypting Files for Alli SFTP
PGP is an asymmetric encryption protocol. Alli SFTPs shares its public key, which is used to encrypt files. Alli SFTP can then use it’s private key to decrypt those files and make them available decrypted to the rest of the Alli Platform (but, noteably, the actual SFTP connection will never see decrypted files).
The examples in this section use gpg
(https://www.gnupg.org/)
1. Download the Alli SFTP Public Key
The key can be found here: https://static.alliplatform.com/allisftp.pem
Ideally, this key is downloaded each time a file is encrypted to ensure the correct key is always used. When Alli rotates its SFTP PGP key, a one-month notice period will be given during which time both the previous and new keys will work.
curl -o allisftp.pem https://static.alliplatform.com/allisftp.pem
2. Import the Public Key into GPG
After retrieving the public key, it must be imported into GPG for use.
gpg --import allisftp.pem
This should produce some output like:
gpg: key B11F05E87C966749: public key "Alli SFTP (Alli SFTP Encryption Key) <sftp@alliplatform.com>" imported
A gpg --list-keys
should now display the key.
pub rsa4096 2023-09-11 [SC]
ABAD5E4A4136A63E87439B1EB11F05E87C966749
uid [ unknown] Alli SFTP (Alli SFTP Encryption Key) <sftp@alliplatform.com>
sub rsa4096 2023-09-11 [E]
3. Encrypt a File
We’ll encrypt a hello.txt
file for this example:
gpg --encrypt --trust-model always --recipient sftp@alliplatform.com --output hello.txt.pgp hello.txt
Because the PGP key was not received from a key server, GPG defaults to not trusting it. --trust-model always
allows encryption to work without a prompt asking whether or not the key is trusted. This step can be skipped by editing the key and trusting it.
gpg --edit-key sftp@alliplatform.com
gpg> trust
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5 # enter 5 here
Do you really want to set this key to ultimate trust? (y/N) y
gpg> quit
The file hello.txt.pgp
will be in your working directory now. This file is in a binary format, opening it in a text editor will show what amounts to gibberish for a human. Alli SFTP can understand both binary encrypted files and ASCII Armored encrypted files. Binary files will be smaller, so favor those where possible.
To create an ASCII armored, encrypted file:
gpg --encrypt --trust-model always --recipient sftp@alliplatform.com --output hello.txt.asc --armor hello.txt
ASCII armored files are in a PEM file format and begin with.
-----BEGIN PGP MESSAGE-----
On Compressed Files
Should you wish to do both; compress (.zip archive or gzip) and encrypt files, compress the file first then encrypt it. Compression algorithms will perform better on plain text and the resulting file will be smaller.
On File Extensions
Common file names for PGP encrypted files are .pgp
for binary encrypted files and .asc
for ASCII armored files.
Alli SFTP supports any file extension but will remove .pgp
and .asc
from the file filename (see below: Using Encrypted Files).
4. Upload the File to Alli SFTP
$ sftp acme.test_encrypted@sftp.alliplatform.com
acme.test_encrypted@sftp.alliplatform.com's password:
Connected to sftp.alliplatform.com.
sftp> put hello_binary.txt.pgp writeable/
Using Encrypted Files in Alli
Alli SFTP acts as an SFTP frontend to Alli Cloud Storage. When an SFTP user has encryption turned on, its files are placed in cloud storage at the path: source=sftp/sftp={username}/encrypted=true/
, which we call the upload path of the SFTP user. This upload path is the only area that can be seen via the SFTP protocol – SFTP connections will only see the encrypted files.
Behind the scenes, a process runs that decrypts the files and places them at the download path for the sftp user: source=sftp/sftp={username}/decrypted=true/
. Grab files from the download path to use them in Alli.
![](../../__attachments/2998009905/Screen%20Shot%202023-09-12%20at%2006.50.51.png?inst-v=9d2044ed-f5d2-41ad-960f-0e53811769aa)
Both of these paths are available via the SFTP api, so retrieving the user from the API using the Alli Access token provided to marketplace executions and using cloud_storage_download_path
from that user is ideal. This API endpoint is https://sftp-api.central.alliplatform.com/sftp_users/{username}
![](../../__attachments/2998009905/Screen%20Shot%202023-09-12%20at%2006.50.17.png?inst-v=9d2044ed-f5d2-41ad-960f-0e53811769aa)
NodeJS Encryption Script Example
Usage: node encrypt.js input_file.txt input_file.txt.pgp
const fs = require('node:fs');
const pgp = require('openpgp')
async function main(inputFile, outputFile) {
// fetch the key and read it into an open pgp public key
const response = await fetch('https://static.alliplatform.com/allisftp.pem')
const armoredKey = await response.text()
const publicKey = await pgp.readKey({
armoredKey: armoredKey,
});
// create the "message" to encrypt with a stream
const inputStream = fs.createReadStream(inputFile);
const message = await pgp.createMessage({
binary: inputStream,
});
// encrypt the message with the key
const encrypted = await pgp.encrypt({
message: message,
format: 'binary',
encryptionKeys: publicKey,
});
const outputStream = fs.createWriteStream(outputFile);
return new Promise((resolve, reject) => {
// then pipe the message to the output stream
const stream = encrypted.pipe(outputStream);
stream.on('error', reject);
stream.on('finish', resolve)
});
}
main(process.argv[2], process.argv[3])
Shell Encryption Script Example
Usage: encrypt.sh hello.txt hello.txt.pgp
#!/usr/bin/env bash
set -e
inputfile="$1"
outputfile="$2"
curl -o allisftp.pem https://static.alliplatform.com/allisftp.pem
# change the gpg home directory so we're working not modify the system keyring
gpgdir="$(mktemp -d gpgtemp.XXXXXXXXXX)"
export GNUPGHOME="$gpgdir"
gpg --import allisftp.pem
gpg --encrypt \
--recipient sftp@alliplatform.com \
--output "$outputfile" \
--trust-model always \
"$inputfile"
rm -rf "$gpgdir"