Skip to content

Commit 49992f4

Browse files
Add Dapr.Cryptography package + fix for large files (#1527)
* Implementation of the new crypto client Signed-off-by: Whit Waldo <[email protected]> Co-authored-by: Christopher Watford <[email protected]>
1 parent 6d92113 commit 49992f4

File tree

49 files changed

+2016
-107
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2016
-107
lines changed

all.sln

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.Generators.Test
111111
EndProject
112112
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.Actors.Generators", "test\Dapr.E2E.Test.Actors.Generators\Dapr.E2E.Test.Actors.Generators.csproj", "{B5CDB0DC-B26D-48F1-B934-FE5C1C991940}"
113113
EndProject
114-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cryptography", "examples\Client\Cryptography\Cryptography.csproj", "{C74FBA78-13E8-407F-A173-4555AEE41FF3}"
115-
EndProject
116114
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Protos", "src\Dapr.Protos\Dapr.Protos.csproj", "{DFBABB04-50E9-42F6-B470-310E1B545638}"
117115
EndProject
118116
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Common", "src\Dapr.Common\Dapr.Common.csproj", "{B445B19C-A925-4873-8CB7-8317898B6970}"
@@ -143,8 +141,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Messaging.Test", "test
143141
EndProject
144142
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Messaging", "src\Dapr.Messaging\Dapr.Messaging.csproj", "{0EAE36A1-B578-4F13-A113-7A477ECA1BDA}"
145143
EndProject
146-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingSubscriptionExample", "examples\Client\PublishSubscribe\StreamingSubscriptionExample\StreamingSubscriptionExample.csproj", "{290D1278-F613-4DF3-9DF5-F37E38CDC363}"
147-
EndProject
148144
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Jobs", "src\Dapr.Jobs\Dapr.Jobs.csproj", "{C8BB6A85-A7EA-40C0-893D-F36F317829B3}"
149145
EndProject
150146
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Jobs.Test", "test\Dapr.Jobs.Test\Dapr.Jobs.Test.csproj", "{BF9828E9-5597-4D42-AA6E-6E6C12214204}"
@@ -169,6 +165,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.Analyzers.Test"
169165
EndProject
170166
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Analyzers.Common", "test\Dapr.Analyzers.Common\Dapr.Analyzers.Common.csproj", "{7E23E229-6823-4D84-AF3A-AE14CEAEF52A}"
171167
EndProject
168+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Cryptography", "src\Dapr.Cryptography\Dapr.Cryptography.csproj", "{160EFFA0-F6B9-49E4-B62B-68C0D53DB425}"
169+
EndProject
170+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Cryptography.Test", "test\Dapr.Cryptography.Test\Dapr.Cryptography.Test.csproj", "{B508EBD6-0F14-480C-A446-45A09052733B}"
171+
EndProject
172+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingSubscriptionExample", "examples\Messaging\StreamingSubscriptionExample\StreamingSubscriptionExample.csproj", "{E070F694-335D-4D96-8951-F41D0A5F2A8B}"
173+
EndProject
174+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cryptography", "Cryptography", "{6843B5B3-9E95-4022-B792-8A1DE6BFEFEC}"
175+
EndProject
176+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cryptography", "examples\Cryptography\Cryptography.csproj", "{097D5F6F-D26F-4BFB-9074-FA52577EB442}"
177+
EndProject
178+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Messaging", "Messaging", "{442E80E5-8040-4123-B88A-26FD36BA95D9}"
179+
EndProject
172180
Global
173181
GlobalSection(SolutionConfigurationPlatforms) = preSolution
174182
Debug|Any CPU = Debug|Any CPU
@@ -445,6 +453,22 @@ Global
445453
{7E23E229-6823-4D84-AF3A-AE14CEAEF52A}.Debug|Any CPU.Build.0 = Debug|Any CPU
446454
{7E23E229-6823-4D84-AF3A-AE14CEAEF52A}.Release|Any CPU.ActiveCfg = Release|Any CPU
447455
{7E23E229-6823-4D84-AF3A-AE14CEAEF52A}.Release|Any CPU.Build.0 = Release|Any CPU
456+
{160EFFA0-F6B9-49E4-B62B-68C0D53DB425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
457+
{160EFFA0-F6B9-49E4-B62B-68C0D53DB425}.Debug|Any CPU.Build.0 = Debug|Any CPU
458+
{160EFFA0-F6B9-49E4-B62B-68C0D53DB425}.Release|Any CPU.ActiveCfg = Release|Any CPU
459+
{160EFFA0-F6B9-49E4-B62B-68C0D53DB425}.Release|Any CPU.Build.0 = Release|Any CPU
460+
{B508EBD6-0F14-480C-A446-45A09052733B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
461+
{B508EBD6-0F14-480C-A446-45A09052733B}.Debug|Any CPU.Build.0 = Debug|Any CPU
462+
{B508EBD6-0F14-480C-A446-45A09052733B}.Release|Any CPU.ActiveCfg = Release|Any CPU
463+
{B508EBD6-0F14-480C-A446-45A09052733B}.Release|Any CPU.Build.0 = Release|Any CPU
464+
{E070F694-335D-4D96-8951-F41D0A5F2A8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
465+
{E070F694-335D-4D96-8951-F41D0A5F2A8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
466+
{E070F694-335D-4D96-8951-F41D0A5F2A8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
467+
{E070F694-335D-4D96-8951-F41D0A5F2A8B}.Release|Any CPU.Build.0 = Release|Any CPU
468+
{097D5F6F-D26F-4BFB-9074-FA52577EB442}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
469+
{097D5F6F-D26F-4BFB-9074-FA52577EB442}.Debug|Any CPU.Build.0 = Debug|Any CPU
470+
{097D5F6F-D26F-4BFB-9074-FA52577EB442}.Release|Any CPU.ActiveCfg = Release|Any CPU
471+
{097D5F6F-D26F-4BFB-9074-FA52577EB442}.Release|Any CPU.Build.0 = Release|Any CPU
448472
EndGlobalSection
449473
GlobalSection(SolutionProperties) = preSolution
450474
HideSolutionNode = FALSE
@@ -497,7 +521,6 @@ Global
497521
{7C06FE2D-6C62-48F5-A505-F0D715C554DE} = {7592AFA4-426B-42F3-AE82-957C86814482}
498522
{AF89083D-4715-42E6-93E9-38497D12A8A6} = {DD020B34-460F-455F-8D17-CF4A949F100B}
499523
{B5CDB0DC-B26D-48F1-B934-FE5C1C991940} = {DD020B34-460F-455F-8D17-CF4A949F100B}
500-
{C74FBA78-13E8-407F-A173-4555AEE41FF3} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
501524
{DFBABB04-50E9-42F6-B470-310E1B545638} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
502525
{B445B19C-A925-4873-8CB7-8317898B6970} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
503526
{CDB47863-BEBD-4841-A807-46D868962521} = {DD020B34-460F-455F-8D17-CF4A949F100B}
@@ -525,6 +548,12 @@ Global
525548
{E49C822C-E921-48DF-897B-3E603CA596D2} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
526549
{A2C0F203-11FF-4B7F-A94F-B9FD873573FE} = {DD020B34-460F-455F-8D17-CF4A949F100B}
527550
{7E23E229-6823-4D84-AF3A-AE14CEAEF52A} = {DD020B34-460F-455F-8D17-CF4A949F100B}
551+
{160EFFA0-F6B9-49E4-B62B-68C0D53DB425} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
552+
{B508EBD6-0F14-480C-A446-45A09052733B} = {DD020B34-460F-455F-8D17-CF4A949F100B}
553+
{6843B5B3-9E95-4022-B792-8A1DE6BFEFEC} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
554+
{097D5F6F-D26F-4BFB-9074-FA52577EB442} = {6843B5B3-9E95-4022-B792-8A1DE6BFEFEC}
555+
{442E80E5-8040-4123-B88A-26FD36BA95D9} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
556+
{E070F694-335D-4D96-8951-F41D0A5F2A8B} = {442E80E5-8040-4123-B88A-26FD36BA95D9}
528557
EndGlobalSection
529558
GlobalSection(ExtensibilityGlobals) = postSolution
530559
SolutionGuid = {65220BF2-EAE1-4CB2-AA58-EBE80768CB40}

daprdocs/content/en/dotnet-sdk-docs/dotnet-ai/dotnet-ai-conversation-howto.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,3 @@ Put the Dapr AI .NET SDK to the test. Walk through the samples to see Dapr in ac
7777

7878
This part of the .NET SDK allows you to interface with the Conversations API to send and receive messages from
7979
large language models.
80-
81-
### Send messages
82-
83-

daprdocs/content/en/dotnet-sdk-docs/dotnet-ai/dotnet-ai-conversation-usage.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ It maintains access to networking resources in the form of TCP sockets used to c
1717
For best performance, create a single long-lived instance of `DaprConversationClient` and provide access to that shared
1818
instance throughout your application. `DaprConversationClient` instances are thread-safe and intended to be shared.
1919

20-
This can be aided by utilizing the dependency injection functionality. The registration method supports registration using
20+
This can be aided by utilizing the dependency injection functionality. The registration method supports registration
2121
as a singleton, a scoped instance or as transient (meaning it's recreated every time it's injected), but also enables
2222
registration to utilize values from an `IConfiguration` or other injected service in a way that's impractical when
2323
creating the client from scratch in each of your classes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
type: docs
3+
title: "Dapr Cryptography .NET SDK"
4+
linkTitle: "Cryptography"
5+
weight: 51000
6+
description: Get up and running with the Dapr Cryptography .NET SDK
7+
---
8+
9+
With the Dapr Cryptography package, you can perform high-performance encryption and decryption operations with Dapr.
10+
11+
To get started with this functionality, walk through the [Dapr Cryptography({{< ref dotnet-cryptography-howto.md >}})
12+
how-to guide.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
type: docs
3+
title: "How to: Create an use Dapr Cryptography in the .NET SDK"
4+
linkTitle: "How to: Use the Cryptography client"
5+
weight: 510100
6+
description: Learn how to create and use the Dapr Cryptography client using the .NET SDK
7+
---
8+
9+
## Prerequisites
10+
- [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0), or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) installed
11+
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
12+
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost)
13+
14+
## Installation
15+
To get started with the Dapr Cryptography client, install the [Dapr.Cryptography package](https://www.nuget.org/packages/Dapr.Cryptography) from NuGet:
16+
```sh
17+
dotnet add package Dapr.Cryptography
18+
```
19+
20+
A `DaprEncryptionClient` maintains access to networking resources in the form of TCP sockets used to communicate with
21+
the Dapr sidecar.
22+
23+
### Dependency Injection
24+
25+
The `AddDaprEncryptionClient()` method will register the Dapr client with dependency injection and is the recommended approach
26+
for using this package. This method accepts an optional options delegate for configuring the `DaprEncryptionClient` and a
27+
`ServiceLifetime` argument, allowing you to specify a different lifetime for the registered services instead of the default `Singleton`
28+
value.
29+
30+
The following example assumes all default values are acceptable and is sufficient to register the `DaprEncryptionClient`:
31+
32+
```csharp
33+
services.AddDaprEncryptionClient();
34+
```
35+
36+
The optional configuration delegate is used to configure the `DaprEncryptionClient` by specifying options on the
37+
`DaprEncryptionClientBuilder` as in the following example:
38+
```csharp
39+
services.AddSingleton<DefaultOptionsProvider>();
40+
services.AddDaprEncryptionClient((serviceProvider, clientBuilder) => {
41+
//Inject a service to source a value from
42+
var optionsProvider = serviceProvider.GetRequiredService<DefaultOptionsProvider>();
43+
var standardTimeout = optionsProvider.GetStandardTimeout();
44+
45+
//Configure the value on the client builder
46+
clientBuilder.UseTimeout(standardTimeout);
47+
});
48+
```
49+
50+
### Manual Instantiation
51+
Rather than using dependency injection, a `DaprEncryptionClient` can also be built using the static client builder.
52+
53+
For best performance, create a single long-lived instance of `DaprEncryptionClient` and provide access to that shared instance throughout
54+
your application. `DaprEncryptionClient` instances are thread-safe and intended to be shared.
55+
56+
Avoid creating a `DaprEncryptionClient` per-operation.
57+
58+
A `DaprEncryptionClient` can be configured by invoking methods on the `DaprEncryptionClientBuilder` class before calling `.Build()`
59+
to create the client. The settings for each `DaprEncryptionClient` are separate and cannot be changed after calling `.Build()`.
60+
61+
```csharp
62+
var daprEncryptionClient = new DaprEncryptionClientBuilder()
63+
.UseJsonSerializerSettings( ... ) //Configure JSON serializer
64+
.Build();
65+
```
66+
67+
See the .NET [documentation here]({{< ref dotnet-client >}}) for more information about the options available when configuring the Dapr client via the builder.
68+
69+
## Try it out
70+
Put the Dapr AI .NET SDK to the test. Walk through the samples to see Dapr in action:
71+
72+
| SDK Samples | Description |
73+
|-------------------------------------------------------------------------------------| ----------- |
74+
| [SDK samples](https://github.com/dapr/dotnet-sdk/tree/master/examples/Cryptography) | Clone the SDK repo to try out some examples and get started. |
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
type: docs
3+
title: "Dapr Cryptography Client"
4+
linkTitle: "Cryptography client"
5+
weight: 510005
6+
description: Learn how to create Dapr Crytography clients
7+
---
8+
9+
The Dapr Cryptography package allows you to perform encryption and decryption operations provided by the Dapr sidecar.
10+
11+
## Lifetime management
12+
A `DaprEncryptionClient` is a version of the Dapr client that is dedicated to interacting with the Dapr Cryptography API.
13+
It can be registered alongside a `DaprClient` and other Dapr clients without issue.
14+
15+
It maintains access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar.
16+
17+
For best performance, create a single long-lived instance of `DaprEncryptionClient` and provide access to that shared
18+
instance throughout your application. `DaprEncryptionClient` instances are thread-safe and intended to be shared.
19+
20+
This can be aided by utilizing the dependency injection functionality. The registration method supports registration
21+
as a singleton, a scoped instance, or as a transient (meaning it's recreated every time it's injected), but also enables
22+
registration to utilize values from an `IConfiguration` or other injected service in a way that's impractical when creating
23+
the client from scratch in each of your classes.
24+
25+
Avoid creating a `DaprEncryptionClient` for each operation.
26+
27+
## Configuring `DaprEncryptionClient` via `DaprEncryptionClientBuilder`
28+
A `DaprCryptographyClient` can be configured by invoking methods on the `DaprEncryptionClientBuilder` class before calling
29+
`.Build()` to create the client itself. The settings for each `DaprEncryptionClientBuilder` are separate can cannot be
30+
changed after calling `.Build()`.
31+
32+
```cs
33+
var daprEncryptionClient = new DaprEncryptionClientBuilder()
34+
.UseDaprApiToken("abc123") //Specify the API token used to authenticate to the Dapr sidecar
35+
.Build();
36+
```
37+
38+
The `DaprEncryptionClientBuilder` contains settings for:
39+
- The HTTP endpoint of the Dapr sidecar
40+
- The gRPC endpoint of the Dapr sidecar
41+
- The `JsonSerializerOptions` object used to configure JSON serialization
42+
- The `GrpcChannelOptions` object used to configure gRPC
43+
- The API token used to authenticate requests to the sidecar
44+
- The factory method used to create the `HttpClient` instance used by the SDK
45+
- The timeout used for the `HttpClient` instance when making requests to the sidecar
46+
47+
The SDK will read the following environment variables to configure the default values:
48+
49+
- `DAPR_HTTP_ENDPOINT`: used to find the HTTP endpoint of the Dapr sidecar, example: `https://dapr-api.mycompany.com`
50+
- `DAPR_GRPC_ENDPOINT`: used to find the gRPC endpoint of the Dapr sidecar, example: `https://dapr-grpc-api.mycompany.com`
51+
- `DAPR_HTTP_PORT`: if `DAPR_HTTP_ENDPOINT` is not set, this is used to find the HTTP local endpoint of the Dapr sidecar
52+
- `DAPR_GRPC_PORT`: if `DAPR_GRPC_ENDPOINT` is not set, this is used to find the gRPC local endpoint of the Dapr sidecar
53+
- `DAPR_API_TOKEN`: used to set the API token
54+
55+
### Configuring gRPC channel options
56+
57+
Dapr's use of `CancellationToken` for cancellation relies on the configuration of the gRPC channel options. If you need
58+
to configure these options yourself, make sure to enable the [ThrowOperationCanceledOnCancellation setting](https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannelOptions.html#Grpc_Net_Client_GrpcChannelOptions_ThrowOperationCanceledOnCancellation).
59+
60+
```cs
61+
var daprEncryptionClient = new DaprEncryptionClientBuilder()
62+
.UseGrpcChannelOptions(new GrpcChannelOptions { .. ThrowOperationCanceledOnCancellation = true })
63+
.Build();
64+
```
65+
66+
## Using cancellation with `DaprEncryptionClient`
67+
The APIs on `DaprEncryptionClient` perform asynchronous operations and accept an optional `CancellationToken` parameter. This
68+
follows a standard .NET practice for cancellable operations. Note that when cancellation occurs, there is no guarantee that
69+
the remote endpoint stops processing the request, only that the client has stopped waiting for completion.
70+
71+
When an operation is cancelled, it will throw an `OperationCancelledException`.
72+
73+
## Configuring `DaprEncryptionClient` via dependency injection
74+
Using the built-in extension methods for registering the `DaprEncryptionClient` in a dependency injection container can
75+
provide the benefit of registering the long-lived service a single time, centralize complex configuration and improve
76+
performance by ensuring similarly long-lived resources are re-purposed when possible (e.g. `HttpClient` instances).
77+
78+
There are three overloads available to give the developer the greatest flexibility in configuring the client for their
79+
scenario. Each of these will register the `IHttpClientFactory` on your behalf if not already registered, and configure
80+
the `DaprEncryptionClientBuilder` to use it when creating the `HttpClient` instance in order to re-use the same instance as
81+
much as possible and avoid socket exhaustion and other issues.
82+
83+
In the first approach, there's no configuration done by the developer and the `DaprEncryptionClient` is configured with the
84+
default settings.
85+
86+
```cs
87+
var builder = WebApplication.CreateBuilder(args);
88+
89+
builder.Services.AddDaprEncryptionClent(); //Registers the `DaprEncryptionClient` to be injected as needed
90+
var app = builder.Build();
91+
```
92+
93+
Sometimes the developer will need to configure the created client using the various configuration options detailed
94+
above. This is done through an overload that passes in the `DaprEncryptionClientBuiler` and exposes methods for configuring
95+
the necessary options.
96+
97+
```cs
98+
var builder = WebApplication.CreateBuilder(args);
99+
100+
builder.Services.AddDaprEncryptionClient((_, daprEncrpyptionClientBuilder) => {
101+
//Set the API token
102+
daprEncryptionClientBuilder.UseDaprApiToken("abc123");
103+
//Specify a non-standard HTTP endpoint
104+
daprEncryptionClientBuilder.UseHttpEndpoint("http://dapr.my-company.com");
105+
});
106+
107+
var app = builder.Build();
108+
```
109+
110+
Finally, it's possible that the developer may need to retrieve information from another service in order to populate
111+
these configuration values. That value may be provided from a `DaprClient` instance, a vendor-specific SDK or some
112+
local service, but as long as it's also registered in DI, it can be injected into this configuration operation via the
113+
last overload:
114+
115+
```cs
116+
var builder = WebApplication.CreateBuilder(args);
117+
118+
//Register a fictional service that retrieves secrets from somewhere
119+
builder.Services.AddSingleton<SecretService>();
120+
121+
builder.Services.AddDaprEncryptionClient((serviceProvider, daprEncryptionClientBuilder) => {
122+
//Retrieve an instance of the `SecretService` from the service provider
123+
var secretService = serviceProvider.GetRequiredService<SecretService>();
124+
var daprApiToken = secretService.GetSecret("DaprApiToken").Value;
125+
126+
//Configure the `DaprEncryptionClientBuilder`
127+
daprEncryptionClientBuilder.UseDaprApiToken(daprApiToken);
128+
});
129+
130+
var app = builder.Build();
131+
```

0 commit comments

Comments
 (0)