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
  • SSL/TLS certificates
  • Private keys

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: String secret inputs support the multi-line format. See the Multi-line secret inputs section for details.

Multi-line secret inputs

For sensitive information that contains line breaks, such as SSL/TLS certificates, private keys, or configuration files, you can combine the multi-line text format with encryption.

Multi-line secret inputs are encrypted using the same AES-256-GCM algorithm as single-line secrets, but they provide a larger text area for input. You can decrypt them using the same methods shown in the Handling the Payload section.

This is particularly useful when you need to send certificates to your backend workflows. For example, when configuring SSL certificates for cloud resources or setting up authentication with certificate-based credentials.

Multiline secrets are not masked

Unlike single-line secret inputs which are masked with asterisks, multi-line secret inputs display the actual text as you type. The value is still encrypted when sent to your backend and is never logged or saved by Port.

API definition

{
"certificateInput": {
"title": "SSL certificate",
"icon": "Lock",
"type": "string",
"format": "multi-line",
"encryption": "aes256-gcm",
"description": "Paste your SSL certificate"
}
}

This configuration creates a multi-line text area where users can paste certificates or other multiline secrets. The value will be encrypted before being sent to your backend.

Common use cases

Multi-line secret inputs are ideal for:

  • SSL/TLS certificates and certificate chains.
  • Private keys (RSA, EC, etc.).
  • JSON or YAML configuration files containing secrets.
  • Multi-line API keys or tokens.
  • SSH keys.

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')