Secrets encryption
Portway automatically encrypts sensitive data in your environment settings files on startup. Connection strings and sensitive headers (containing words like "password", "secret", "token", etc.) are encrypted using RSA + AES hybrid encryption to keep your data safe at rest.
How It Works
On startup, Portway:
- Checks for encryption keys in the
.corefolder - If keys don't exist, it generates a new RSA 2048-bit keypair automatically
- It scans all environment folders (
environments/*/settings.json) - Any unencrypted connection strings or sensitive headers are automatically encrypted
- The encrypted values are saved back to the settings files
Key Storage:
- Private key:
.core/recovery.binlz4(encrypted withPORTWAY_ENCRYPTION_KEY) - Public key:
.core/snapshot_blob.bin
Encryption Key Management
Setting the Encryption Key
The PORTWAY_ENCRYPTION_KEY is used to protect the private key. Priority order:
Windows Machine Environment Variable (recommended for production):
powershell[System.Environment]::SetEnvironmentVariable('PORTWAY_ENCRYPTION_KEY', 'your-secure-key-here', 'Machine')Process Environment Variable:
powershell$env:PORTWAY_ENCRYPTION_KEY = 'your-secure-key-here'.env file (for Docker):
bashPORTWAY_ENCRYPTION_KEY=your-secure-key-hereFallback: A hardcoded key (not recommended for production)
Regenerating Keys
If you need to regenerate encryption keys:
- Stop the application
- Delete the
.corefolder - (Optional) Set a new
PORTWAY_ENCRYPTION_KEY - Restart the application - new keys will be generated
- All environment files will be re-encrypted with the new keys
Warning: If you change PORTWAY_ENCRYPTION_KEY without deleting .core, the application won't be able to decrypt the existing private key and encryption will fail.
What Gets Encrypted
Always encrypted:
ConnectionStringfield (if valid MSSQL format)
Conditionally encrypted (headers containing these keywords):
- password
- secret
- token
- key
- auth
- credential
- signature
- hmac
- bearer
Example - Before encryption:
{
"ServerName": "localhost",
"ConnectionString": "Server=localhost;Database=MyDB;User ID=sa;Password=mypass;",
"Headers": {
"ApiToken": "secret-token-123"
}
}After encryption:
{
"ServerName": "localhost",
"ConnectionString": "PWENC:aG5kc2...::dG9rZW4=",
"Headers": {
"ApiToken": "PWENC:bXlzZW...::c2VjcmV0"
}
}Validation
Connection strings are validated before encryption. They must have:
DataSource(server name)InitialCatalog(database name)- Either
IntegratedSecurity=trueOR validUserIDandPassword
Invalid connection strings will not be encrypted and an error will be logged:
[ERR] Invalid MSSQL connection string format in environment 'MyEnv' - skipping encryption.Troubleshooting
File Permission Errors
If you see:
[ERR] Access denied when saving to C:\...\settings.jsonSolution: Remove the read-only flag:
# Single file
Set-ItemProperty "C:\Apps\Portway API\v1\environments\prod\settings.json" -Name IsReadOnly -Value $false
# All settings files
Get-ChildItem "C:\Apps\Portway API\v1\environments\*\settings.json" | ForEach-Object { $_.IsReadOnly = $false }Decryption Failures
If the application can't decrypt settings on startup:
[ERR] Failed to load or decrypt private key from .core/recovery.binlz4Causes:
- The
PORTWAY_ENCRYPTION_KEYwas changed after keys were generated - The
.core/recovery.binlz4file is corrupted - Wrong encryption key is being used
Solution: Delete the .core folder and restart to regenerate keys.
Viewing Logs
Enable debug logging to see encryption details:
In appsettings.json:
{
"Serilog": {
"MinimumLevel": {
"Default": "Debug"
}
}
}You'll see:
[DBG] Scanning all environments for values to encrypt
[DBG] Found 3 environment(s): 500,700, Synergy
[DBG] Encrypted ConnectionString for environment: 600
[DBG] Encryption scan complete: 3 encrypted, 0 already encrypted, 0 errorsSecurity Notes
Set a strong PORTWAY_ENCRYPTION_KEY in production using a machine-level environment variable. Back up the .core folder securely, without it you cannot decrypt your settings. Never commit .core to source control. Use different encryption keys for different environments.