Theme
PGP Preview
Everything on this page works on local files, by path, on the Connector's own disk.
Passphrases belong in the secret store
A private key passphrase is a credential, and it should not be typed into a script. Put it in the secret store and read it with GetSecret():
js
var passphrase = GetSecret("pgp-passphrase");
DecryptPGPFile("/in/report.pgp", "/out/report.csv", "/opt/keys/acme.privkey", passphrase);Generating a key pair
js
function GeneratePGPKeys(keyPairName: string, directory: string, bits: number): boolean;Writes <directory>/<keyPairName>.pubkey and <directory>/<keyPairName>.privkey, both ASCII armored. Use 4096 bits unless you have a reason not to.
js
if (GeneratePGPKeys("acme", "/opt/keys", 4096)) {
Log.Info("wrote /opt/keys/acme.pubkey and /opt/keys/acme.privkey");
}Generating keys from a script is rarely what you want
A key pair generated by a handler is generated again every time that handler fires, overwriting the previous one and silently invalidating everything encrypted to it. Generate keys once, deliberately, outside the automation, and have scripts only use them.
Put private keys in a directory the Connector service account can read and nobody else can:
chown sc-conn:sc-conn /opt/keys
chmod 700 /opt/keys
chmod 600 /opt/keys/*.privkeyEncrypting and decrypting
js
function PGPEncryptFile(inputFile, outputFile, recipientPubKey): boolean;
function PGPDecryptFile(inputFile, outputFile, recipientPrivKey): boolean;Encryption needs only the recipient's public key. Decryption needs your private key.
js
var local = "/var/staging/" + ShortUID() + ".csv";
var vfs = GetCurrentVFS();
if (!vfs.ExportFile(CtxRelPath(), local).Ok()) {
Log.Error("could not export " + CtxRelPath());
Exit(1);
}
if (PGPEncryptFile(local, local + ".pgp", "/opt/keys/partner.pubkey")) {
var cli = new SftpClient();
cli.Host = "sftp.partner.com:22";
cli.User = "acme";
cli.KeyFile = "/opt/keys/id_ed25519";
cli.HostKeySHA256 = partnerHostKey;
if (cli.Connect()) {
cli.Upload(local + ".pgp", "/incoming");
cli.Close();
}
DelFile(local + ".pgp");
}
SecureErase(local);Note the last line. ExportFile wrote plaintext to local disk; delete it, and prefer SecureErase when the content was sensitive.
Signing and verifying
js
function PGPSignFile(inFile, sigFile, pubKeyFile, privKeyFile): boolean;
function PGPVerifyFile(inFile, sigFile, pubKeyFile): boolean;These produce and check a detached signature. The file itself is not encrypted; the signature proves who signed it and that it has not changed since.
js
PGPSignFile("/var/outbox/report.csv",
"/var/outbox/report.csv.sig",
"/opt/keys/acme.pubkey",
"/opt/keys/acme.privkey");js
var valid = PGPVerifyFile("/var/inbox/report.csv",
"/var/inbox/report.csv.sig",
"/opt/keys/partner.pubkey");
if (!valid) {
Log.Error("signature check FAILED for /var/inbox/report.csv");
Exit(1);
}A false verification means do not use the file
false means one of three things: the file was altered, the wrong public key was supplied, or the signature file is damaged. You cannot tell which from the return value, and it does not matter: none of them permits you to treat the file as authentic. Stop, log, and get a human involved.
Which encryption to use
The Connector gives you three separate things that all say "encryption", and they solve different problems:
| Mechanism | Protects | Configure it |
|---|---|---|
| Encryption at rest | Files sitting in your storage, against someone who reads the disk | Console, per virtual file system |
| OTFE on a remote client | Files you push to somewhere you do not fully trust | cli.Options.OTFE |
| PGP, this page | Files sent to a specific named party, who alone can open them | Your script |
They compose. A file can be encrypted at rest in your storage, exported, PGP encrypted to a partner, and uploaded over an OTFE enabled SFTP link. Most of the time you want the first, and PGP only when a partner has asked for it by name.
None of these protects a file from your own scripts
GetCurrentVFS() decrypts at rest storage transparently, and ExportFile writes plaintext to local disk. Encryption at rest defends against someone carrying the disk away. It does not defend against code running inside the Connector, which is why who can write scripts matters as much as which encryption you turned on.