-
Notifications
You must be signed in to change notification settings - Fork 39
Fix/decryption section for workflows #577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
clairekinde11
wants to merge
10
commits into
main
Choose a base branch
from
Fix/Decryption-section-for-workflows
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
357448d
New section: decryption
clairekinde11 0eff0c9
Apply suggestion from @coderabbitai[bot]
clairekinde11 43055bf
Add .NET code snippet for workflow payload decryption
clairekinde11 e61394e
Delete src/content/docs/workflows/manage-workflows/workflow-encryptio…
clairekinde11 b35cd39
Create decrypt-keys-workflow.mdx
clairekinde11 2766d58
Delete src/content/docs/workflows/manage-workflows/decrypt-keys-workf…
clairekinde11 c0da735
Create encrypt-decrypt-workflows.mdx
clairekinde11 f25a36d
Update encrypt-decrypt-workflows.mdx
clairekinde11 30e196e
Update encrypt-decrypt-workflows.mdx
clairekinde11 2432a1b
URL update
clairekinde11 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
227 changes: 227 additions & 0 deletions
227
src/content/docs/workflows/manage-workflows/encrypt-decrypt-workflows.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
--- | ||
page_id: 961c2bf6-2683-4339-b42a-928e328ce74b | ||
title: Workflow encryption key | ||
sidebar: | ||
order: 3 | ||
relatedArticles: | ||
- d672fca7-6c6a-49f8-85c9-6e86ce99f440 | ||
- 8554d648-fc2f-4ef9-aaa9-4f27b3c05205 | ||
description: Learn about workflow encryption keys used to secure sensitive data transmission in secure fetch operations and other encrypted workflow communications in Kinde workflows. | ||
topics: | ||
- "workflows" | ||
- "manage-workflows" | ||
- "security" | ||
sdk: null | ||
languages: | ||
- "TypeScript" | ||
- "JavaScript" | ||
- "C#" | ||
- ".NET" | ||
audience: | ||
- "developers" | ||
- "admins" | ||
complexity: "intermediate" | ||
keywords: | ||
- "encryption key" | ||
- "security" | ||
- "secure fetch" | ||
- "sensitive data" | ||
- "encryption" | ||
updated: "2025-09-29" | ||
featured: false | ||
deprecated: false | ||
ai_summary: "Documentation for workflow encryption keys used to secure sensitive data transmission in secure fetch operations and other encrypted workflow communications." | ||
--- | ||
|
||
You can generate unique encryption keys to be used to make secure API calls within your workflows. | ||
|
||
Encryption keys protect sensitive data and should be updated regularly for continued protection. | ||
|
||
Keys are per-workflow, so you can have different keys for different workflows. You can also have multiple keys for a single workflow, but only one key can be active at a time. | ||
|
||
## How encryption keys work | ||
|
||
When an POST request is made using the [kinde.secureFetch binding](/workflows/bindings/secure-fetch-binding/), the body is automatically encrypted with the active encryption key for the workflow. Use the same encryption key in your own code to decrypt the payload on arrival. This ensures secure transfer of the data. | ||
|
||
## Add an encryption key to a workflow | ||
|
||
1. Go to **Workflows** and select a workflow. | ||
2. Select **Encryption keys** in the menu. | ||
3. Select **Add encryption key**. A dialog appears, enabling you to copy the key. You need to copy it immediately, as it cannot be viewed again. | ||
4. After you copy the key, select **Close**. If this is the first key you have added, it will automatically be made **active**. | ||
5. Add the key to your code, to decrypt data sent from Kinde. | ||
|
||
## Decrypt workflow‑encrypted payloads | ||
|
||
Decrypting methods depend on your systems and framework. Here's how to decrypt if you are using .NET. | ||
|
||
Situation: You use `kinde.secureFetch` and the payload is encrypted with your workflow’s active encryption key using AES-GCM, then encoded in Base64. | ||
|
||
Method: Decrypt the request body in your .NET API: | ||
|
||
1. In Base64, decode the incoming payload. | ||
2. In AES-GCM, decrypt the decoded data using your workflow’s active encryption key (the one you created in the Kinde dashboard). | ||
3. In .NET, for example, use the `System.Security.Cryptography.AesGcm` class for decryption. | ||
|
||
The payload structure includes the nonce (IV), tag, and ciphertext. These will be provided in the encrypted request payload, so your code should parse them out before decrypting. | ||
|
||
```csharp | ||
using System; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using System.Text.Json; | ||
|
||
public class WorkflowPayloadDecryptor | ||
{ | ||
private readonly byte[] _encryptionKey; | ||
|
||
public WorkflowPayloadDecryptor(string base64EncryptionKey) | ||
{ | ||
_encryptionKey = Convert.FromBase64String(base64EncryptionKey); | ||
} | ||
|
||
public string DecryptPayload(string encryptedPayload) | ||
{ | ||
try | ||
{ | ||
// Step 1: Base64 decode the incoming payload | ||
byte[] encryptedData = Convert.FromBase64String(encryptedPayload); | ||
|
||
// Step 2: Parse the payload structure | ||
// The payload contains: nonce (12 bytes) + tag (16 bytes) + ciphertext | ||
const int nonceLength = 12; | ||
const int tagLength = 16; | ||
|
||
if (encryptedData.Length < nonceLength + tagLength) | ||
{ | ||
throw new ArgumentException("Invalid encrypted payload structure"); | ||
} | ||
|
||
// Extract components | ||
byte[] nonce = new byte[nonceLength]; | ||
byte[] tag = new byte[tagLength]; | ||
byte[] ciphertext = new byte[encryptedData.Length - nonceLength - tagLength]; | ||
|
||
Array.Copy(encryptedData, 0, nonce, 0, nonceLength); | ||
Array.Copy(encryptedData, nonceLength, tag, 0, tagLength); | ||
Array.Copy(encryptedData, nonceLength + tagLength, ciphertext, 0, ciphertext.Length); | ||
|
||
// Step 3: Decrypt using AES-GCM | ||
using (var aesGcm = new AesGcm(_encryptionKey)) | ||
{ | ||
byte[] decryptedBytes = new byte[ciphertext.Length]; | ||
aesGcm.Decrypt(nonce, ciphertext, tag, decryptedBytes); | ||
|
||
// Convert decrypted bytes to string | ||
return Encoding.UTF8.GetString(decryptedBytes); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new InvalidOperationException("Failed to decrypt workflow payload", ex); | ||
} | ||
} | ||
} | ||
|
||
// Example usage in an ASP.NET Core controller | ||
[ApiController] | ||
[Route("api/[controller]")] | ||
public class WorkflowController : ControllerBase | ||
{ | ||
private readonly WorkflowPayloadDecryptor _decryptor; | ||
|
||
public WorkflowController(IConfiguration configuration) | ||
{ | ||
// Get the encryption key from configuration | ||
string encryptionKey = configuration["KindeWorkflowEncryptionKey"]; | ||
_decryptor = new WorkflowPayloadDecryptor(encryptionKey); | ||
} | ||
|
||
[HttpPost("webhook")] | ||
public async Task<IActionResult> HandleWorkflowWebhook() | ||
{ | ||
try | ||
{ | ||
// Read the encrypted payload from the request body | ||
using var reader = new StreamReader(Request.Body); | ||
string encryptedPayload = await reader.ReadToEndAsync(); | ||
|
||
// Decrypt the payload | ||
string decryptedJson = _decryptor.DecryptPayload(encryptedPayload); | ||
|
||
// Parse the decrypted JSON | ||
var workflowData = JsonSerializer.Deserialize<WorkflowData>(decryptedJson); | ||
|
||
// Process the decrypted data | ||
// ... your business logic here ... | ||
|
||
return Ok(new { message = "Workflow payload processed successfully" }); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return BadRequest(new { error = "Failed to process workflow payload", details = ex.Message }); | ||
} | ||
} | ||
} | ||
|
||
// Example data model for the decrypted payload | ||
public class WorkflowData | ||
{ | ||
public string UserId { get; set; } | ||
public string EventType { get; set; } | ||
public Dictionary<string, object> Data { get; set; } | ||
} | ||
``` | ||
|
||
### Configuration | ||
|
||
Add your workflow encryption key to your `appsettings.json`: | ||
|
||
```json | ||
{ | ||
"KindeWorkflowEncryptionKey": "your-base64-encoded-encryption-key-here" | ||
} | ||
``` | ||
|
||
Or set it as an environment variable: | ||
|
||
```bash | ||
KindeWorkflowEncryptionKey=your-base64-encoded-encryption-key-here | ||
``` | ||
|
||
## Update an encryption key | ||
|
||
1. Go to **Workflows** and select a workflow. | ||
2. Select **Encryption keys** in the menu. | ||
3. Select **Add encryption key**. A dialog opens with information about adding the key. | ||
4. Select **Add**. A dialog appears showing the key value. | ||
5. Copy the key value and store it somewhere you can access again. | ||
6. Select **Close**. | ||
7. When you are ready to update the key in your code, select the three dots menu on the new key, then select **Activate**. A dialog opens, confirming the action. | ||
8. Select **Activate encryption key**. This makes the new key active and deactivates the previously active key. | ||
9. Add the new key value to your code, to continue decrypting data sent from Kinde. | ||
|
||
## Deactivate/activate an encryption key | ||
|
||
You can change the active status of any key. Remember to update your code to use the active key. | ||
|
||
1. Go to **Workflows** and select a workflow. | ||
2. Select **Encryption keys** in the menu. | ||
3. To deactivate an active key: | ||
1. Select the three dots menu on the active key. | ||
2. Select **Deactivate**. A confirmation window opens. | ||
3. Follow the prompts and select **Deactivate encryption key.** | ||
4. To activate a deactivated key: | ||
1. Select the three dots menu on the inactive key. An inactive key shows no status. | ||
2. Select **Activate**. A confirmation window opens. | ||
3. Follow the prompts and select **Activate encryption key**. This makes the new key active and deactivates any previously active key. | ||
|
||
## Delete used or unwanted encryption keys | ||
|
||
Deleting used keys is good security hygiene. But deleting an active key can also break your code. Only delete inactive keys. | ||
|
||
1. Go to **Workflows** and select a workflow. | ||
2. Select **Encryption keys** in the menu. | ||
3. Next to an inactive key, select the three dots menu. | ||
4. Select **Delete key**. A confirmation window opens. | ||
5. Follow the prompts and select **Delete encryption key**. |
87 changes: 0 additions & 87 deletions
87
src/content/docs/workflows/manage-workflows/workflow-encryption-key.mdx
This file was deleted.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the missing
using
directives so the sample compiles.The C# snippet references
StreamReader
,ControllerBase
,IConfiguration
,Task<IActionResult>
, andDictionary<string, object>
, but the code block only imports core namespaces. Without the matchingusing
statements (System.IO
,System.Collections.Generic
,System.Threading.Tasks
,Microsoft.AspNetCore.Mvc
,Microsoft.Extensions.Configuration
), readers copying the sample will hit compile errors. Please prepend the snippet with the full set of namespaces (or annotate them inline) so the example builds cleanly.🤖 Prompt for AI Agents