diff --git a/daprdocs/content/en/developing-applications/building-blocks/cryptography/cryptography-overview.md b/daprdocs/content/en/developing-applications/building-blocks/cryptography/cryptography-overview.md index a09937323..79792f588 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/cryptography/cryptography-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/cryptography/cryptography-overview.md @@ -67,7 +67,7 @@ Want to put the Dapr cryptography API to the test? Walk through the following qu | Quickstart/tutorial | Description | | ------------------- | ----------- | -| Cryptography quickstart | Coming soon | +| [Cryptography quickstart]({{< ref cryptography-quickstart.md >}}) | Encrypt and decrypt messages and large files using RSA and AES keys with the cryptography API. | ### Start using cryptography directly in your app diff --git a/daprdocs/content/en/getting-started/quickstarts/_index.md b/daprdocs/content/en/getting-started/quickstarts/_index.md index 949ee85b2..ff16bc218 100644 --- a/daprdocs/content/en/getting-started/quickstarts/_index.md +++ b/daprdocs/content/en/getting-started/quickstarts/_index.md @@ -31,3 +31,4 @@ Hit the ground running with our Dapr quickstarts, complete with code samples aim | [Configuration]({{< ref configuration-quickstart.md >}}) | Get configuration items and subscribe for configuration updates. | | [Resiliency]({{< ref resiliency >}}) | Define and apply fault-tolerance policies to your Dapr API requests. | | [Workflow]({{< ref workflow-quickstart.md >}}) | Orchestrate business workflow activities in long running, fault-tolerant, stateful applications. | +| [Cryptography]({{< ref cryptography-quickstart.md >}}) | Encrypt and decrypt data using Dapr's cryptographic APIs. | diff --git a/daprdocs/content/en/getting-started/quickstarts/cryptography-quickstart.md b/daprdocs/content/en/getting-started/quickstarts/cryptography-quickstart.md new file mode 100644 index 000000000..3dbcdd3f5 --- /dev/null +++ b/daprdocs/content/en/getting-started/quickstarts/cryptography-quickstart.md @@ -0,0 +1,288 @@ +--- +type: docs +title: "Quickstart: Cryptography" +linkTitle: Cryptography +weight: 79 +description: Get started with the Dapr Cryptography building block +--- + +{{% alert title="Alpha" color="warning" %}} +The cryptography building block is currently in **alpha**. +{{% /alert %}} + +Let's take a look at the Dapr [cryptography building block]({{< ref cryptography >}}). In this Quickstart, you'll create an application that encrypts and decrypts data using the Dapr cryptography APIs. You'll: + +- Encrypt and then decrypt a short string (using an RSA key), reading the result in-memory, in a Go byte slice. +- Encrypt and then decrypt a large file (using an AES key), storing the encrypted and decrypted data to files using streams. + + + +{{% alert title="Note" color="primary" %}} +This example uses the Dapr SDK, which leverages gRPC and is **strongly** recommended when using cryptographic APIs to encrypt and decrypt messages. +{{% /alert %}} + +Currently, you can experience the cryptography API using the Go SDK. + +{{< tabs "Go" >}} + + +{{% codetab %}} + +> This quickstart includes a Go application called `crypto-quickstart`. + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Latest version of Go](https://go.dev/dl/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + +- [OpenSSL](https://www.openssl.org/source/) available on your system + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/cryptography) + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +In the terminal, from the root directory, navigate to the cryptography sample. + +```bash +cd cryptography/go/sdk +``` + +### Step 2: Run the application with Dapr + +Navigate into the folder with the source code: + +```bash +cd ./crypto-quickstart +``` + +The application code defines two required keys: +- Private RSA key +- A 256-bit symmetric (AES) key + +Generate two keys, an RSA key and and AES key using OpenSSL and write these to two files: + +```bash +mkdir -p keys +# Generate a private RSA key, 4096-bit keys +openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out keys/rsa-private-key.pem +# Generate a 256-bit key for AES +openssl rand -out keys/symmetric-key-256 32 +``` + +Run the Go service app with Dapr: + +```bash +dapr run --app-id crypto-quickstart --resources-path ../../../components/ -- go run . +``` + +**Expected output** + +``` +== APP == dapr client initializing for: 127.0.0.1:52407 +== APP == Encrypted the message, got 856 bytes +== APP == Decrypted the message, got 24 bytes +== APP == The secret is "passw0rd" +== APP == Wrote decrypted data to encrypted.out +== APP == Wrote decrypted data to decrypted.out.jpg +``` + +### What happened? + +#### `local-storage.yaml` + +Earlier, you created a directory inside `crypto-quickstarts` called `keys`. In [the `local-storage` component YAML](https://github.com/dapr/quickstarts/tree/master/cryptography/components/local-storage.yaml), the `path` metadata maps to the newly created `keys` directory. + +```yml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: localstorage +spec: + type: crypto.dapr.localstorage + version: v1 + metadata: + - name: path + # Path is relative to the folder where the example is located + value: ./keys +``` + +#### `app.go` + +[The application file](https://github.com/dapr/quickstarts/tree/master/cryptography/go/sdk/crypto-quickstart/app.go) encrypts and decrypts messages and files using the RSA and AES keys that you generated. The application creates a new Dapr SDK client: + +```go +func main() { + // Create a new Dapr SDK client + client, err := dapr.NewClient() + + //... + + // Step 1: encrypt a string using the RSA key, then decrypt it and show the output in the terminal + encryptDecryptString(client) + + // Step 2: encrypt a large file and then decrypt it, using the AES key + encryptDecryptFile(client) +} +``` + +##### Encrypting and decrypting a string using the RSA key + +Once the client is created, the application encrypts a message: + +```go +func encryptDecryptString(client dapr.Client) { + // ... + + // Encrypt the message + encStream, err := client.Encrypt(context.Background(), + strings.NewReader(message), + dapr.EncryptOptions{ + ComponentName: CryptoComponentName, + // Name of the key to use + // Since this is a RSA key, we specify that as key wrapping algorithm + KeyName: RSAKeyName, + KeyWrapAlgorithm: "RSA", + }, + ) + + // ... + + // The method returns a readable stream, which we read in full in memory + encBytes, err := io.ReadAll(encStream) + // ... + + fmt.Printf("Encrypted the message, got %d bytes\n", len(encBytes)) +``` + +The application then decrypts the message: + +```go + // Now, decrypt the encrypted data + decStream, err := client.Decrypt(context.Background(), + bytes.NewReader(encBytes), + dapr.DecryptOptions{ + // We just need to pass the name of the component + ComponentName: CryptoComponentName, + // Passing the name of the key is optional + KeyName: RSAKeyName, + }, + ) + + // ... + + // The method returns a readable stream, which we read in full in memory + decBytes, err := io.ReadAll(decStream) + + // ... + + // Print the message on the console + fmt.Printf("Decrypted the message, got %d bytes\n", len(decBytes)) + fmt.Println(string(decBytes)) +} +``` + +##### Encrypt and decrpyt a large file using the AES key + +Next, the application encrypts a large image file: + +```go +func encryptDecryptFile(client dapr.Client) { + const fileName = "liuguangxi-66ouBTTs_x0-unsplash.jpg" + + // Get a readable stream to the input file + plaintextF, err := os.Open(fileName) + + // ... + + defer plaintextF.Close() + + // Encrypt the file + encStream, err := client.Encrypt(context.Background(), + plaintextF, + dapr.EncryptOptions{ + ComponentName: CryptoComponentName, + // Name of the key to use + // Since this is a symmetric key, we specify AES as key wrapping algorithm + KeyName: SymmetricKeyName, + KeyWrapAlgorithm: "AES", + }, + ) + + // ... + + // Write the encrypted data to a file "encrypted.out" + encryptedF, err := os.Create("encrypted.out") + + // ... + + encryptedF.Close() + + fmt.Println("Wrote decrypted data to encrypted.out") +``` + +The application then decrypts the large image file: + +```go + // Now, decrypt the encrypted data + // First, open the file "encrypted.out" again, this time for reading + encryptedF, err = os.Open("encrypted.out") + + // ... + + defer encryptedF.Close() + + // Now, decrypt the encrypted data + decStream, err := client.Decrypt(context.Background(), + encryptedF, + dapr.DecryptOptions{ + // We just need to pass the name of the component + ComponentName: CryptoComponentName, + // Passing the name of the key is optional + KeyName: SymmetricKeyName, + }, + ) + + // ... + + // Write the decrypted data to a file "decrypted.out.jpg" + decryptedF, err := os.Create("decrypted.out.jpg") + + // ... + + decryptedF.Close() + + fmt.Println("Wrote decrypted data to decrypted.out.jpg") +} +``` + +{{% /codetab %}} + + +{{< /tabs >}} + +## Watch the demo + +Watch this [demo video of the cryptography API from the Dapr Community Call #83](https://youtu.be/PRWYX4lb2Sg?t=1148): + + + +## Tell us what you think! + +We're continuously working to improve our Quickstart examples and value your feedback. Did you find this Quickstart helpful? Do you have suggestions for improvement? + +Join the discussion in our [discord channel](https://discord.com/channels/778680217417809931/953427615916638238). + +## Next steps + +- Walk through [more examples of encrypting and decrypting using the cryptography API]({{< ref howto-cryptography.md >}}) +- Learn more about [cryptography as a Dapr building block]({{< ref cryptography-overview.md >}}) + +{{< button text="Explore Dapr tutorials >>" page="getting-started/tutorials/_index.md" >}} diff --git a/daprdocs/content/en/reference/api/workflow_api.md b/daprdocs/content/en/reference/api/workflow_api.md index e784e52e1..80814852e 100644 --- a/daprdocs/content/en/reference/api/workflow_api.md +++ b/daprdocs/content/en/reference/api/workflow_api.md @@ -12,8 +12,8 @@ Dapr provides users with the ability to interact with workflows and comes with a Start a workflow instance with the given name and optionally, an instance ID. -```http -POST http://localhost:3500/v1.0-alpha1/workflows///start[?instanceId=] +``` +POST http://localhost:3500/v1.0-alpha1/workflows///start[?instanceID=] ``` Note that workflow instance IDs can only contain alphanumeric characters, underscores, and dashes. @@ -24,7 +24,7 @@ Parameter | Description --------- | ----------- `workflowComponentName` | Use `dapr` for Dapr Workflows `workflowName` | Identify the workflow type -`instanceId` | (Optional) Unique value created for each run of a specific workflow +`instanceID` | (Optional) Unique value created for each run of a specific workflow ### Request content @@ -52,7 +52,7 @@ The API call will provide a response similar to this: Terminate a running workflow instance with the given name and instance ID. -```http +``` POST http://localhost:3500/v1.0-alpha1/workflows///terminate ``` @@ -79,7 +79,7 @@ This API does not return any content. For workflow components that support subscribing to external events, such as the Dapr Workflow engine, you can use the following "raise event" API to deliver a named event to a specific workflow instance. -```http +``` POST http://localhost:3500/v1.0-alpha1/workflows///raiseEvent/ ``` @@ -112,7 +112,7 @@ None. Pause a running workflow instance. -```http +``` POST http://localhost:3500/v1.0-alpha1/workflows///pause ``` @@ -139,7 +139,7 @@ None. Resume a paused workflow instance. -```http +``` POST http://localhost:3500/v1.0-alpha1/workflows///resume ``` @@ -166,7 +166,7 @@ None. Purge the workflow state from your state store with the workflow's instance ID. -```http +``` POST http://localhost:3500/v1.0-alpha1/workflows///purge ``` @@ -193,7 +193,7 @@ None. Get information about a given workflow instance. -```http +``` GET http://localhost:3500/v1.0-alpha1/workflows// ``` diff --git a/daprdocs/static/images/crypto-quickstart.png b/daprdocs/static/images/crypto-quickstart.png new file mode 100644 index 000000000..e6f7fe70f Binary files /dev/null and b/daprdocs/static/images/crypto-quickstart.png differ