Skip to main content

Check out Port for yourselfย 

Secret

Secret input is an input type used to pass secrets and sensitive information to action backends, the values sent via the secret input go through an additional layer of encryption using your private key. In addition, the values sent via the secret input are not logged or saved by Port.

๐Ÿ’ก Common Secret Usageโ€‹

The secret input type can be used for sensitive information, such as:

  • Cloud secrets
  • Passwords
  • API keys
  • Secret tokens

Secret Input Structureโ€‹

A secret input is defined as a regular input, but with the additional encryption field which specifies the encryption algorithm to use:

{
"mySecretInput": {
"title": "My secret input",
"icon": "My icon",
"type": "string",
"encryption": "aes256-gcm",
"description": "My entity input"
}
}
  • aes256-gcm - This will encrypt the property data using 256 bits AES in GCM mode. The encrypted value will be prefixed by the 16 bits IV and suffixed by the 16 bits MAC, encoded to base-64. The encryption key will be the first 32 bytes of your organization's Client Secret.

Supported Typesโ€‹

{
"mySecretInput": {
"title": "My secret input",
"icon": "My icon",
"type": "string",
"encryption": "aes256-gcm",
"description": "My entity input"
}
}

Note: it is unsupported to have the a format for secrets inputs.

Handling the Payloadโ€‹

The payload sent to your infrastructure will contain the encrypted value of your secret property inputs. To make use of your secret inputs, you will need to decrypt them:

Examplesโ€‹

Examples for decrypting properties encrypted with the aes256-gcm algorithm.

The following example uses the flask and pycryptodome packages:

import base64
import json
import os

from flask import Flask, request
from Crypto.Cipher import AES

PORT_CLIENT_SECRET = 'YOUR PORT CLIENT SECRET'
PROPERY_IS_JSON = False # whether the property is defined as json or not (string otherwise)

app = Flask(__name__)

@app.route('/', methods=['POST'])
def webhook():
# initialize the aes cipher
key = PORT_CLIENT_SECRET[:32].encode()

req = request.get_json(silent=True, force=True)
encrypted_property_value = base64.b64decode(req.get('payload').get('properties').get('secret-property'))

iv = encrypted_property_value[:16]
ciphertext = encrypted_property_value[16:-16]
mac = encrypted_property_value[-16:]

cipher = AES.new(key, AES.MODE_GCM, iv)

# decrypt the property
decrypted_property_value = cipher.decrypt_and_verify(ciphertext, mac)
property_value = json.loads(decrypted_property_value) if PROPERY_IS_JSON else decrypted_property_value

return property_value # this is the original value the user sent

if __name__ == '__main__':
port = int(os.getenv('PORT', 80))

print("Starting app on port %d" % port)

app.run(debug=False, port=port, host='0.0.0.0')