This is the multi-page printable view of this section. Click here to print.
Manage Dapr configuration
- 1: Dapr configuration
- 2: How-To: Control concurrency and rate limit applications
- 3: How-To: Limit the secrets that can be read from secret stores
- 4: How-To: Apply access control list configuration for service invocation
- 5: How-To: Selectively enable Dapr APIs on the Dapr sidecar
- 6: How-To: Configure Dapr to use gRPC
- 7: How-To: Handle large HTTP header size
- 8: How-To: Handle large http body requests
- 9: How-To: Install certificates in the Dapr sidecar
- 10: How-To: Enable preview features
- 11: How-To: Configure Environment Variables from Secrets for Dapr sidecar
1 - Dapr configuration
Dapr configurations are settings and policies that enable you to change both the behavior of individual Dapr applications, or the global behavior of the Dapr control plane system services.
for more information, read the configuration concept.
Application configuration
Set up application configuration
You can set up application configuration either in self-hosted or Kubernetes mode.
In self hosted mode, the Dapr configuration is a configuration file - for example, config.yaml
. By default, the Dapr sidecar looks in the default Dapr folder for the runtime configuration:
- Linux/MacOs:
$HOME/.dapr/config.yaml
- Windows:
%USERPROFILE%\.dapr\config.yaml
An application can also apply a configuration by using a --config
flag to the file path with dapr run
CLI command.
In Kubernetes mode, the Dapr configuration is a Configuration resource, that is applied to the cluster. For example:
kubectl apply -f myappconfig.yaml
You can use the Dapr CLI to list the Configuration resources for applications.
dapr configurations -k
A Dapr sidecar can apply a specific configuration by using a dapr.io/config
annotation. For example:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/config: "myappconfig"
Note: See all Kubernetes annotations available to configure the Dapr sidecar on activation by sidecar Injector system service.
Application configuration settings
The following menu includes all of the configuration settings you can set on the sidecar.
- Tracing
- Metrics
- Logging
- Middleware
- Name resolution
- Scope secret store access
- Access Control allow lists for building block APIs
- Access Control allow lists for service invocation API
- Disallow usage of certain component types
- Turning on preview features
- Example sidecar configuration
Tracing
Tracing configuration turns on tracing for an application.
The tracing
section under the Configuration
spec contains the following properties:
tracing:
samplingRate: "1"
otel:
endpointAddress: "otelcollector.observability.svc.cluster.local:4317"
zipkin:
endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"
The following table lists the properties for tracing:
Property | Type | Description |
---|---|---|
samplingRate |
string | Set sampling rate for tracing to be enabled or disabled. |
stdout |
bool | True write more verbose information to the traces |
otel.endpointAddress |
string | Set the Open Telemetry (OTEL) server address to send traces to. This may or may not require the https:// or http:// depending on your OTEL provider. |
otel.isSecure |
bool | Is the connection to the endpoint address encrypted |
otel.protocol |
string | Set to http or grpc protocol |
zipkin.endpointAddress |
string | Set the Zipkin server address to send traces to. This should include the protocol (http:// or https://) on the endpoint. |
samplingRate
samplingRate
is used to enable or disable the tracing. The valid range of samplingRate
is between 0
and 1
inclusive. The sampling rate determines whether a trace span should be sampled or not based on value.
samplingRate : "1"
samples all traces. By default, the sampling rate is (0.0001), or 1 in 10,000 traces.
To disable the sampling rate, set samplingRate : "0"
in the configuration.
otel
The OpenTelemetry (otel
) endpoint can also be configured via an environment variable. The presence of the OTEL_EXPORTER_OTLP_ENDPOINT
environment variable
turns on tracing for the sidecar.
Environment Variable | Description |
---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
Sets the Open Telemetry (OTEL) server address, turns on tracing |
OTEL_EXPORTER_OTLP_INSECURE |
Sets the connection to the endpoint as unencrypted (true/false) |
OTEL_EXPORTER_OTLP_PROTOCOL |
Transport protocol (grpc , http/protobuf , http/json ) |
See Observability distributed tracing for more information.
Metrics
The metrics
section under the Configuration
spec can be used to enable or disable metrics for an application.
The metrics
section contains the following properties:
metrics:
enabled: true
rules: []
latencyDistributionBuckets: []
http:
increasedCardinality: true
pathMatching:
- /items
- /orders/{orderID}
- /orders/{orderID}/items/{itemID}
- /payments/{paymentID}
- /payments/{paymentID}/status
- /payments/{paymentID}/refund
- /payments/{paymentID}/details
excludeVerbs: false
recordErrorCodes: true
In the examples above, the path filter /orders/{orderID}/items/{itemID}
would return a single metric count matching all the orderID
s and all the itemID
s, rather than multiple metrics for each itemID
. For more information, see HTTP metrics path matching.
The above example also enables recording error code metrics, which is disabled by default.
The following table lists the properties for metrics:
Property | Type | Description |
---|---|---|
enabled |
boolean | When set to true, the default, enables metrics collection and the metrics endpoint. |
rules |
array | Named rule to filter metrics. Each rule contains a set of labels to filter on and a regex expression to apply to the metrics path. |
latencyDistributionBuckets |
array | Array of latency distribution buckets in milliseconds for latency metrics histograms. |
http.increasedCardinality |
boolean | When set to true (default), in the Dapr HTTP server each request path causes the creation of a new “bucket” of metrics. This can cause issues, including excessive memory consumption, when there many different requested endpoints (such as when interacting with RESTful APIs).To mitigate high memory usage and egress costs associated with high cardinality metrics with the HTTP server, you should set the metrics.http.increasedCardinality property to false . |
http.pathMatching |
array | Array of paths for path matching, allowing users to define matching paths to manage cardinality. |
http.excludeVerbs |
boolean | When set to true (default is false), the Dapr HTTP server ignores each request HTTP verb when building the method metric label. |
To further help manage cardinality, path matching allows you to match specified paths according to defined patterns, reducing the number of unique metrics paths and thus controlling metric cardinality. This feature is particularly useful for applications with dynamic URLs, ensuring that metrics remain meaningful and manageable without excessive memory consumption.
Using rules, you can set regular expressions for every metric exposed by the Dapr sidecar. For example:
metrics:
enabled: true
rules:
- name: dapr_runtime_service_invocation_req_sent_total
labels:
- name: method
regex:
"orders/": "orders/.+"
See metrics documentation for more information.
Logging
The logging
section under the Configuration
spec is used to configure how logging works in the Dapr Runtime.
The logging
section contains the following properties:
logging:
apiLogging:
enabled: false
obfuscateURLs: false
omitHealthChecks: false
The following table lists the properties for logging:
Property | Type | Description |
---|---|---|
apiLogging.enabled |
boolean | The default value for the --enable-api-logging flag for daprd (and the corresponding dapr.io/enable-api-logging annotation): the value set in the Configuration spec is used as default unless a true or false value is passed to each Dapr Runtime. Default: false . |
apiLogging.obfuscateURLs |
boolean | When enabled, obfuscates the values of URLs in HTTP API logs (if enabled), logging the abstract route name rather than the full path being invoked, which could contain Personal Identifiable Information (PII). Default: false . |
apiLogging.omitHealthChecks |
boolean | If true , calls to health check endpoints (e.g. /v1.0/healthz ) are not logged when API logging is enabled. This is useful if those calls are adding a lot of noise in your logs. Default: false |
See logging documentation for more information.
Middleware
Middleware configuration sets named HTTP pipeline middleware handlers. The httpPipeline
and the appHttpPipeline
section under the Configuration
spec contain the following properties:
httpPipeline: # for incoming http calls
handlers:
- name: oauth2
type: middleware.http.oauth2
- name: uppercase
type: middleware.http.uppercase
appHttpPipeline: # for outgoing http calls
handlers:
- name: oauth2
type: middleware.http.oauth2
- name: uppercase
type: middleware.http.uppercase
The following table lists the properties for HTTP handlers:
Property | Type | Description |
---|---|---|
name |
string | Name of the middleware component |
type |
string | Type of middleware component |
See Middleware pipelines for more information.
Name resolution component
You can set name resolution components to use within the configuration file. For example, to set the spec.nameResolution.component
property to "sqlite"
, pass configuration options in the spec.nameResolution.configuration
dictionary as shown below.
This is a basic example of a configuration resource:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
nameResolution:
component: "sqlite"
version: "v1"
configuration:
connectionString: "/home/user/.dapr/nr.db"
For more information, see:
- The name resolution component documentation for more examples.
- The Configuration file documentation to learn more about how to configure name resolution per component.
Scope secret store access
See the Scoping secrets guide for information and examples on how to scope secrets to an application.
Access Control allow lists for building block APIs
See the guide for selectively enabling Dapr APIs on the Dapr sidecar for information and examples on how to set access control allow lists (ACLs) on the building block APIs lists.
Access Control allow lists for service invocation API
See the Allow lists for service invocation guide for information and examples on how to set allow lists with ACLs which use the service invocation API.
Disallow usage of certain component types
Using the components.deny
property in the Configuration
spec you can specify a denylist of component types that cannot be initialized.
For example, the configuration below disallows the initialization of components of type bindings.smtp
and secretstores.local.file
:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
spec:
components:
deny:
- bindings.smtp
- secretstores.local.file
Optionally, you can specify a version to disallow by adding it at the end of the component name. For example, state.in-memory/v1
disables initializing components of type state.in-memory
and version v1
, but does not disable a (hypothetical) v2
version of the component.
Note
When you add the component type secretstores.kubernetes
to the denylist, Dapr forbids the creation of additional components of type secretstores.kubernetes
.
However, it does not disable the built-in Kubernetes secret store, which is:
- Created by Dapr automatically
- Used to store secrets specified in Components specs
If you want to disable the built-in Kubernetes secret store, you need to use the dapr.io/disable-builtin-k8s-secret-store
annotation.
Turning on preview features
See the preview features guide for information and examples on how to opt-in to preview features for a release.
Enabling preview features unlock new capabilities to be added for dev/test, since they still need more time before becoming generally available (GA) in the runtime.
Example sidecar configuration
The following YAML shows an example configuration file that can be applied to an applications’ Dapr sidecar.
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
tracing:
samplingRate: "1"
stdout: true
otel:
endpointAddress: "localhost:4317"
isSecure: false
protocol: "grpc"
httpPipeline:
handlers:
- name: oauth2
type: middleware.http.oauth2
secrets:
scopes:
- storeName: localstore
defaultAccess: allow
deniedSecrets: ["redis-password"]
components:
deny:
- bindings.smtp
- secretstores.local.file
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1
httpVerb: ['POST', 'GET']
action: deny
- name: /op2/*
httpVerb: ["*"]
action: allow
Control plane configuration
A single configuration file called daprsystem
is installed with the Dapr control plane system services that applies global settings.
This is only set up when Dapr is deployed to Kubernetes.
Control plane configuration settings
A Dapr control plane configuration contains the following sections:
mtls
for mTLS (Mutual TLS)
mTLS (Mutual TLS)
The mtls
section contains properties for mTLS.
Property | Type | Description |
---|---|---|
enabled |
bool | If true, enables mTLS for communication between services and apps in the cluster. |
allowedClockSkew |
string | Allowed tolerance when checking the expiration of TLS certificates, to allow for clock skew. Follows the format used by Go’s time.ParseDuration. Default is 15m (15 minutes). |
workloadCertTTL |
string | How long a certificate TLS issued by Dapr is valid for. Follows the format used by Go’s time.ParseDuration. Default is 24h (24 hours). |
sentryAddress |
string | Hostname port address for connecting to the Sentry server. |
controlPlaneTrustDomain |
string | Trust domain for the control plane. This is used to verify connection to control plane services. |
tokenValidators |
array | Additional Sentry token validators to use for authenticating certificate requests. |
See the mTLS how-to and security concepts for more information.
Example control plane configuration
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
allowedClockSkew: 15m
workloadCertTTL: 24h
Next steps
Learn about concurrency and rate limits2 - How-To: Control concurrency and rate limit applications
Typically, in distributed computing, you may only want to allow for a given number of requests to execute concurrently. Using Dapr’s app-max-concurrency
, you can control how many requests and events can invoke your application simultaneously.
Default app-max-concurreny
is set to -1
, meaning no concurrency limit is enforced.
Different approaches
While this guide focuses on app-max-concurrency
, you can also limit request rate per second using the middleware.http.ratelimit
middleware. However, it’s important to understand the difference between the two approaches:
middleware.http.ratelimit
: Time bound and limits the number of requests per secondapp-max-concurrency
: Specifies the max number of concurrent requests (and events) at any point of time.
See Rate limit middleware for more information about that approach.
Demo
Watch this video on how to control concurrency and rate limiting.
Configure app-max-concurrency
Without using Dapr, you would need to create some sort of a semaphore in the application and take care of acquiring and releasing it.
Using Dapr, you don’t need to make any code changes to your application.
Select how you’d like to configure app-max-concurrency
.
To set concurrency limits with the Dapr CLI for running on your local dev machine, add the app-max-concurrency
flag:
dapr run --app-max-concurrency 1 --app-port 5000 python ./app.py
The above example effectively turns your app into a sequential processing service.
To configure concurrency limits in Kubernetes, add the following annotation to your pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodesubscriber
namespace: default
labels:
app: nodesubscriber
spec:
replicas: 1
selector:
matchLabels:
app: nodesubscriber
template:
metadata:
labels:
app: nodesubscriber
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodesubscriber"
dapr.io/app-port: "3000"
dapr.io/app-max-concurrency: "1"
#...
Limitations
Controlling concurrency on external requests
Rate limiting is guaranteed for every event coming from Dapr, including pub/sub events, direct invocation from other services, bindings events, etc. However, Dapr can’t enforce the concurrency policy on requests that are coming to your app externally.
Related links
Next steps
Limit secret store access3 - How-To: Limit the secrets that can be read from secret stores
In addition to scoping which applications can access a given component, you can also scope a named secret store component to one or more secrets for an application. By defining allowedSecrets
and/or deniedSecrets
lists, you restrict applications to access only specific secrets.
In addition to scoping which applications can access a given component, you can also scope a named secret store component to one or more secrets for an application. By defining allowedSecrets
and/or deniedSecrets
lists, you restrict applications to access only specific secrets.
For more information about configuring a Configuration resource:
- Configuration overview
- Configuration schema For more information about configuring a Configuration resource:
- Configuration overview
- Configuration schema
Configure secrets access
The secrets
section under the Configuration
spec contains the following properties:
secrets:
scopes:
- storeName: kubernetes
defaultAccess: allow
allowedSecrets: ["redis-password"]
- storeName: localstore
defaultAccess: allow
deniedSecrets: ["redis-password"]
The following table lists the properties for secret scopes:
Property | Type | Description |
---|---|---|
storeName | string | Name of the secret store component. storeName must be unique within the list |
defaultAccess | string | Access modifier. Accepted values “allow” (default) or “deny” |
allowedSecrets | list | List of secret keys that can be accessed |
deniedSecrets | list | List of secret keys that cannot be accessed |
When an allowedSecrets
list is present with at least one element, only those secrets defined in the list can be accessed by the application.
Permission priority
The allowedSecrets
and deniedSecrets
list values take priority over the defaultAccess
. See how this works in the following example scenarios:
Scenarios | defaultAccess |
allowedSecrets |
deniedSecrets |
permission |
|
---|---|---|---|---|---|
1 | Only default access | deny /allow |
empty | empty | deny /allow |
2 | Default deny with allowed list | deny |
["s1" ] |
empty | only "s1" can be accessed |
3 | Default allow with denied list | allow |
empty | ["s1" ] |
only "s1" cannot be accessed |
4 | Default allow with allowed list | allow |
["s1" ] |
empty | only "s1" can be accessed |
5 | Default deny with denied list | deny |
empty | ["s1" ] |
deny |
6 | Default deny/allow with both lists | deny /allow |
["s1" ] |
["s2" ] |
only "s1" can be accessed |
Examples
Scenario 1: Deny access to all secrets for a secret store
In a Kubernetes cluster, the native Kubernetes secret store is added to your Dapr application by default. In some scenarios, it may be necessary to deny access to Dapr secrets for a given application. To add this configuration: In a Kubernetes cluster, the native Kubernetes secret store is added to your Dapr application by default. In some scenarios, it may be necessary to deny access to Dapr secrets for a given application. To add this configuration:
-
Define the following
appconfig.yaml
. -
Define the following
appconfig.yaml
.apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: appconfig spec: secrets: scopes: - storeName: kubernetes defaultAccess: deny
apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: appconfig spec: secrets: scopes: - storeName: kubernetes defaultAccess: deny
-
Apply it to the Kubernetes cluster using the following command:
kubectl apply -f appconfig.yaml`.
For applications that you need to deny access to the Kubernetes secret store, follow the Kubernetes instructions, adding the following annotation to the application pod.
-
Apply it to the Kubernetes cluster using the following command:
kubectl apply -f appconfig.yaml`.
For applications that you need to deny access to the Kubernetes secret store, follow the Kubernetes instructions, adding the following annotation to the application pod.
dapr.io/config: appconfig
With this defined, the application no longer has access to Kubernetes secret store.
Scenario 2: Allow access to only certain secrets in a secret store
Scenario 2: Allow access to only certain secrets in a secret store
To allow a Dapr application to have access to only certain secrets, define the following config.yaml
:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
secrets:
scopes:
- storeName: vault
defaultAccess: deny
allowedSecrets: ["secret1", "secret2"]
This example defines configuration for secret store named vault
. The default access to the secret store is deny
. Meanwhile, some secrets are accessible by the application based on the allowedSecrets
list. Follow the Sidecar configuration instructions to apply configuration to the sidecar.
This example defines configuration for secret store named vault
. The default access to the secret store is deny
. Meanwhile, some secrets are accessible by the application based on the allowedSecrets
list. Follow the Sidecar configuration instructions to apply configuration to the sidecar.
Scenario 3: Deny access to certain sensitive secrets in a secret store
Define the following config.yaml
:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
secrets:
scopes:
- storeName: vault
defaultAccess: allow # this is the default value, line can be omitted
deniedSecrets: ["secret1", "secret2"]
This configuration explicitly denies access to secret1
and secret2
from the secret store named vault,
while allowing access to all other secrets. Follow the Sidecar configuration instructions to apply configuration to the sidecar.
Next steps
Service invocation access controlThis configuration explicitly denies access to secret1
and secret2
from the secret store named vault,
while allowing access to all other secrets. Follow the Sidecar configuration instructions to apply configuration to the sidecar.
Next steps
Service invocation access control4 - How-To: Apply access control list configuration for service invocation
Using access control, you can configure policies that restrict what the operations calling applications can perform, via service invocation, on the called application. You can define an access control policy specification in the Configuration schema to limit access:
- To a called application from specific operations, and
- To HTTP verbs from the calling applications.
An access control policy is specified in Configuration and applied to the Dapr sidecar for the called application. Access to the called app is based on the matched policy action.
You can provide a default global action for all calling applications. If no access control policy is specified, the default behavior is to allow all calling applications to access to the called app.
See examples of access policies.
Terminology
trustDomain
A “trust domain” is a logical group that manages trust relationships. Every application is assigned a trust domain, which can be specified in the access control list policy spec. If no policy spec is defined or an empty trust domain is specified, then a default value “public” is used. This trust domain is used to generate the identity of the application in the TLS cert.
App Identity
Dapr requests the sentry service to generate a SPIFFE ID for all applications. This ID is attached in the TLS cert.
The SPIFFE ID is of the format: **spiffe://\<trustdomain>/ns/\<namespace\>/\<appid\>**
.
For matching policies, the trust domain, namespace, and app ID values of the calling app are extracted from the SPIFFE ID in the TLS cert of the calling app. These values are matched against the trust domain, namespace, and app ID values specified in the policy spec. If all three of these match, then more specific policies are further matched.
Configuration properties
The following tables lists the different properties for access control, policies, and operations:
Access Control
Property | Type | Description |
---|---|---|
defaultAction |
string | Global default action when no other policy is matched |
trustDomain |
string | Trust domain assigned to the application. Default is “public”. |
policies |
string | Policies to determine what operations the calling app can do on the called app |
Policies
Property | Type | Description |
---|---|---|
app |
string | AppId of the calling app to allow/deny service invocation from |
namespace |
string | Namespace value that needs to be matched with the namespace of the calling app |
trustDomain |
string | Trust domain that needs to be matched with the trust domain of the calling app. Default is “public” |
defaultAction |
string | App level default action in case the app is found but no specific operation is matched |
operations |
string | operations that are allowed from the calling app |
Operations
Property | Type | Description |
---|---|---|
name |
string | Path name of the operations allowed on the called app. Wildcard “*” can be used in a path to match. Wildcard “**” can be used to match under multiple paths. |
httpVerb |
list | List specific http verbs that can be used by the calling app. Wildcard “*” can be used to match any http verb. Unused for grpc invocation. |
action |
string | Access modifier. Accepted values “allow” (default) or “deny” |
Policy rules
- If no access policy is specified, the default behavior is to allow all apps to access to all methods on the called app.
- If no global default action is specified and no app specific policies defined, the empty access policy is treated like no access policy is specified. The default behavior is to allow all apps to access to all methods on the called app.
- If no global default action is specified but some app specific policies have been defined, then we resort to a more secure option of assuming the global default action to deny access to all methods on the called app.
- If an access policy is defined and if the incoming app credentials cannot be verified, then the global default action takes effect.
- If either the trust domain or namespace of the incoming app do not match the values specified in the app policy, the app policy is ignored and the global default action takes effect.
Policy priority
The action corresponding to the most specific policy matched takes effect as ordered below:
- Specific HTTP verbs in the case of HTTP or the operation level action in the case of GRPC.
- The default action at the app level
- The default action at the global level
Example scenarios
Below are some example scenarios for using access control list for service invocation. See configuration guidance to understand the available configuration settings for an application sidecar.
Scenario 1:
Deny access to all apps except where trustDomain
= public
, namespace
= default
, appId
= app1
With this configuration, all calling methods with appId
= app1
are allowed. All other invocation requests from other applications are denied.
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "default"
Scenario 2:
Deny access to all apps except trustDomain
= public
, namespace
= default
, appId
= app1
, operation
= op1
With this configuration, only the method op1
from appId
= app1
is allowed. All other method requests from all other apps, including other methods on app1
, are denied.
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1
httpVerb: ['*']
action: allow
Scenario 3:
Deny access to all apps except when a specific verb for HTTP and operation for GRPC is matched
With this configuration, only the scenarios below are allowed access. All other method requests from all other apps, including other methods on app1
or app2
, are denied.
trustDomain
=public
,namespace
=default
,appID
=app1
,operation
=op1
,httpVerb
=POST
/PUT
trustDomain
="myDomain"
,namespace
="ns1"
,appID
=app2
,operation
=op2
and application protocol is GRPC
Only the httpVerb
POST
/PUT
on method op1
from appId
= app1
are allowe. All other method requests from all other apps, including other methods on app1
, are denied.
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1
httpVerb: ['POST', 'PUT']
action: allow
- appId: app2
defaultAction: deny
trustDomain: 'myDomain'
namespace: "ns1"
operations:
- name: /op2
action: allow
Scenario 4:
Allow access to all methods except trustDomain
= public
, namespace
= default
, appId
= app1
, operation
= /op1/*
, all httpVerb
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1/*
httpVerb: ['*']
action: deny
Scenario 5:
Allow access to all methods for trustDomain
= public
, namespace
= ns1
, appId
= app1
and deny access to all methods for trustDomain
= public
, namespace
= ns2
, appId
= app1
This scenario shows how applications with the same app ID while belonging to different namespaces can be specified.
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "ns1"
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "ns2"
Scenario 6:
Allow access to all methods except trustDomain
= public
, namespace
= default
, appId
= app1
, operation
= /op1/**/a
, all httpVerb
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1/**/a
httpVerb: ['*']
action: deny
“hello world” examples
In these examples, you learn how to apply access control to the hello world tutorials.
Access control lists rely on the Dapr Sentry service to generate the TLS certificates with a SPIFFE ID for authentication. This means the Sentry service either has to be running locally or deployed to your hosting environment, such as a Kubernetes cluster.
The nodeappconfig
example below shows how to deny access to the neworder
method from the pythonapp
, where the Python app is in the myDomain
trust domain and default
namespace. The Node.js app is in the public
trust domain.
nodeappconfig.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: nodeappconfig
spec:
tracing:
samplingRate: "1"
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: pythonapp
defaultAction: allow
trustDomain: 'myDomain'
namespace: "default"
operations:
- name: /neworder
httpVerb: ['POST']
action: deny
pythonappconfig.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pythonappconfig
spec:
tracing:
samplingRate: "1"
accessControl:
defaultAction: allow
trustDomain: "myDomain"
Self-hosted mode
When walking through this tutorial, you:
- Run the Sentry service locally with mTLS enabled
- Set up necessary environment variables to access certificates
- Launch both the Node app and Python app each referencing the Sentry service to apply the ACLs
Prerequisites
- Become familiar with running Sentry service in self-hosted mode with mTLS enabled
- Clone the hello world tutorial
Run the Node.js app
-
In a command prompt, set these environment variables:
```bash export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt` export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt` export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key` export NAMESPACE=default ```
```powershell $env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt) $env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt) $env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key) $env:NAMESPACE="default" ```
-
Run daprd to launch a Dapr sidecar for the Node.js app with mTLS enabled, referencing the local Sentry service:
daprd --app-id nodeapp --dapr-grpc-port 50002 -dapr-http-port 3501 --log-level debug --app-port 3000 --enable-mtls --sentry-address localhost:50001 --config nodeappconfig.yaml
-
Run the Node.js app in a separate command prompt:
node app.js
Run the Python app
-
In another command prompt, set these environment variables:
```bash export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt` export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt` export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key` export NAMESPACE=default
$env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt) $env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt) $env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key) $env:NAMESPACE="default"
-
Run daprd to launch a Dapr sidecar for the Python app with mTLS enabled, referencing the local Sentry service:
daprd --app-id pythonapp --dapr-grpc-port 50003 --metrics-port 9092 --log-level debug --enable-mtls --sentry-address localhost:50001 --config pythonappconfig.yaml
-
Run the Python app in a separate command prompt:
python app.py
You should see the calls to the Node.js app fail in the Python app command prompt, due to the deny operation action in the nodeappconfig
file. Change this action to allow and re-run the apps to see this call succeed.
Kubernetes mode
Prerequisites
- Become familiar with running Sentry service in self-hosted mode with mTLS enabled
- Clone the hello world tutorial
Configure the Node.js and Python apps
You can create and apply the above nodeappconfig.yaml
and pythonappconfig.yaml
configuration files, as described in the configuration.
For example, the Kubernetes Deployment below is how the Python app is deployed to Kubernetes in the default namespace with this pythonappconfig
configuration file.
Do the same for the Node.js deployment and look at the logs for the Python app to see the calls fail due to the deny operation action set in the nodeappconfig
file.
Change this action to allow and re-deploy the apps to see this call succeed.
Deployment YAML example
apiVersion: apps/v1
kind: Deployment
metadata:
name: pythonapp
namespace: default
labels:
app: python
spec:
replicas: 1
selector:
matchLabels:
app: python
template:
metadata:
labels:
app: python
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "pythonapp"
dapr.io/config: "pythonappconfig"
spec:
containers:
- name: python
image: dapriosamples/hello-k8s-python:edge
Demo
Watch this video on how to apply access control list for service invocation.
Next steps
Dapr APIs allow list5 - How-To: Selectively enable Dapr APIs on the Dapr sidecar
In scenarios such as zero trust networks or when exposing the Dapr sidecar to external traffic through a frontend, it’s recommended to only enable the Dapr sidecar APIs being used by the app. Doing so reduces the attack surface and helps keep the Dapr APIs scoped to the actual needs of the application.
Dapr allows you to control which APIs are accessible to the application by setting an API allowlist or denylist using a Dapr Configuration.
Default behavior
If no API allowlist or denylist is specified, the default behavior is to allow access to all Dapr APIs.
- If you’ve only defined a denylist, all Dapr APIs are allowed except those defined in the denylist
- If you’ve only defined an allowlist, only the Dapr APIs listed in the allowlist are allowed
- If you’ve defined both an allowlist and a denylist, the denylist overrides the allowlist for APIs that are defined in both.
- If neither is defined, all APIs are allowed.
For example, the following configuration enables all APIs for both HTTP and gRPC:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
tracing:
samplingRate: "1"
Using an allowlist
Enabling specific HTTP APIs
The following example enables the state v1.0
HTTP API and blocks all other HTTP APIs:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
allowed:
- name: state
version: v1.0
protocol: http
Enabling specific gRPC APIs
The following example enables the state v1
gRPC API and blocks all other gRPC APIs:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
allowed:
- name: state
version: v1
protocol: grpc
Using a denylist
Disabling specific HTTP APIs
The following example disables the state v1.0
HTTP API, allowing all other HTTP APIs:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
denied:
- name: state
version: v1.0
protocol: http
Disabling specific gRPC APIs
The following example disables the state v1
gRPC API, allowing all other gRPC APIs:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
denied:
- name: state
version: v1
protocol: grpc
List of Dapr APIs
The name
field takes the name of the Dapr API you would like to enable.
See this list of values corresponding to the different Dapr APIs:
API group | HTTP API | gRPC API |
---|---|---|
Service Invocation | invoke (v1.0 ) |
invoke (v1 ) |
State | state (v1.0 and v1.0-alpha1 ) |
state (v1 and v1alpha1 ) |
Pub/Sub | publish (v1.0 and v1.0-alpha1 ) |
publish (v1 and v1alpha1 ) |
Output Bindings | bindings (v1.0 ) |
bindings (v1 ) |
Subscribe | n/a | subscribe (v1alpha1 ) |
Secrets | secrets (v1.0 ) |
secrets (v1 ) |
Actors | actors (v1.0 ) |
actors (v1 ) |
Metadata | metadata (v1.0 ) |
metadata (v1 ) |
Configuration | configuration (v1.0 and v1.0-alpha1 ) |
configuration (v1 and v1alpha1 ) |
Distributed Lock | lock (v1.0-alpha1 )unlock (v1.0-alpha1 ) |
lock (v1alpha1 )unlock (v1alpha1 ) |
Cryptography | crypto (v1.0-alpha1 ) |
crypto (v1alpha1 ) |
Workflow | workflows (v1.0 ) |
workflows (v1 ) |
Conversation | conversation (v1.0-alpha1 ) |
conversation (v1alpha1 ) |
Health | healthz (v1.0 ) |
n/a |
Shutdown | shutdown (v1.0 ) |
shutdown (v1 ) |
Next steps
Configure Dapr to use gRPC6 - How-To: Configure Dapr to use gRPC
Dapr implements both an HTTP and a gRPC API for local calls. gRPC is useful for low-latency, high performance scenarios and has language integration using the proto clients. You can see the full list of auto-generated clients (Dapr SDKs).
The Dapr runtime implements a proto service that apps can communicate with via gRPC.
Not only can you call Dapr via gRPC, Dapr can communicate with an application via gRPC. To do that, the app needs to host a gRPC server and implement the Dapr appcallback
service
Configuring Dapr to communicate with an app via gRPC
When running in self hosted mode, use the --app-protocol
flag to tell Dapr to use gRPC to talk to the app:
dapr run --app-protocol grpc --app-port 5005 node app.js
This tells Dapr to communicate with your app via gRPC over port 5005
.
On Kubernetes, set the following annotations in your deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-protocol: "grpc"
dapr.io/app-port: "5005"
#...
Next steps
Handle large HTTP header sizes7 - How-To: Handle large HTTP header size
Dapr has a default limit of 4KB for the HTTP header read buffer size. If you’re sending HTTP headers larger than the default 4KB, you may encounter a Too big request header
service invocation error.
You can increase the HTTP header size by using:
- The
dapr.io/http-read-buffer-size
annotation, or - The
--dapr-http-read-buffer-size
flag when using the CLI.
When running in self-hosted mode, use the --dapr-http-read-buffer-size
flag to configure Dapr to use non-default http header size:
dapr run --dapr-http-read-buffer-size 16 node app.js
This tells Dapr to set maximum read buffer size to 16
KB.
On Kubernetes, set the following annotations in your deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/http-read-buffer-size: "16"
#...
Related links
Dapr Kubernetes pod annotations spec
Next steps
Handle large HTTP body requests8 - How-To: Handle large http body requests
By default, Dapr has a limit for the request body size, set to 4MB. You can change this by defining:
- The
dapr.io/http-max-request-size
annotation, or - The
--dapr-http-max-request-size
flag.
When running in self-hosted mode, use the --dapr-http-max-request-size
flag to configure Dapr to use non-default request body size:
dapr run --dapr-http-max-request-size 16 node app.js
This tells Dapr to set maximum request body size to 16
MB.
On Kubernetes, set the following annotations in your deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/http-max-request-size: "16"
#...
Related links
Dapr Kubernetes pod annotations spec
Next steps
Install sidecar certificates9 - How-To: Install certificates in the Dapr sidecar
The Dapr sidecar can be configured to trust certificates for communicating with external services. This is useful in scenarios where a self-signed certificate needs to be trusted, such as:
- Using an HTTP binding
- Configuring an outbound proxy for the sidecar
Both certificate authority (CA) certificates and leaf certificates are supported.
You can make the following configurations when the sidecar is running as a container.
- Configure certificates to be available to the sidecar container using volume mounts.
- Point the environment variable
SSL_CERT_DIR
in the sidecar container to the directory containing the certificates.
Note: For Windows containers, make sure the container is running with administrator privileges so it can install the certificates.
The following example uses Docker Compose to install certificates (present locally in the ./certificates
directory) in the sidecar container:
version: '3'
services:
dapr-sidecar:
image: "daprio/daprd:edge" # dapr version must be at least v1.8
command: [
"./daprd",
"-app-id", "myapp",
"-app-port", "3000",
]
volumes:
- "./components/:/components"
- "./certificates:/certificates" # (STEP 1) Mount the certificates folder to the sidecar container
environment:
- "SSL_CERT_DIR=/certificates" # (STEP 2) Set the environment variable to the path of the certificates folder
# Uncomment the line below for Windows containers
# user: ContainerAdministrator
Note: When the sidecar is not running inside a container, certificates must be directly installed on the host operating system.
On Kubernetes:
- Configure certificates to be available to the sidecar container using a volume mount.
- Point the environment variable
SSL_CERT_DIR
in the sidecar container to the directory containing the certificates.
The following example YAML shows a deployment that:
- Attaches a pod volume to the sidecar
- Sets
SSL_CERT_DIR
to install the certificates
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/volume-mounts: "certificates-vol:/tmp/certificates" # (STEP 1) Mount the certificates folder to the sidecar container
dapr.io/env: "SSL_CERT_DIR=/tmp/certificates" # (STEP 2) Set the environment variable to the path of the certificates folder
spec:
volumes:
- name: certificates-vol
hostPath:
path: /certificates
#...
Note: When using Windows containers, the sidecar container is started with admin privileges, which is required to install the certificates. This does not apply to Linux containers.
After following these steps, all the certificates in the directory pointed by SSL_CERT_DIR
are installed.
- On Linux containers: All the certificate extensions supported by OpenSSL are supported. Learn more.
- On Windows container: All the certificate extensions supported by
certoc.exe
are supported. See certoc.exe present in Windows Server Core.
Demo
Watch the demo on using installing SSL certificates and securely using the HTTP binding in community call 64:
Related links
- HTTP binding spec
- (Kubernetes) How-to: Mount Pod volumes to the Dapr sidecar
- Dapr Kubernetes pod annotations spec
Next steps
Enable preview features10 - How-To: Enable preview features
Preview features in Dapr are considered experimental when they are first released. These preview features require you to explicitly opt-in to use them. You specify this opt-in in Dapr’s Configuration file.
Preview features are enabled on a per application basis by setting configuration when running an application instance.
Configuration properties
The features
section under the Configuration
spec contains the following properties:
Property | Type | Description |
---|---|---|
name |
string | The name of the preview feature that is enabled/disabled |
enabled |
bool | Boolean specifying if the feature is enabled or disabled |
Enabling a preview feature
Preview features are specified in the configuration. Here is an example of a full configuration that contains multiple features:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: featureconfig
spec:
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"
features:
- name: Feature1
enabled: true
- name: Feature2
enabled: true
To enable preview features when running Dapr locally, either update the default configuration or specify a separate config file using dapr run
.
The default Dapr config is created when you run dapr init
, and is located at:
- Windows:
%USERPROFILE%\.dapr\config.yaml
- Linux/macOS:
~/.dapr/config.yaml
Alternately, you can update preview features on all apps run locally by specifying the --config
flag in dapr run
and pointing to a separate Dapr config file:
dapr run --app-id myApp --config ./previewConfig.yaml ./app
In Kubernetes mode, the configuration must be provided via a configuration component. Using the same configuration as above, apply it via kubectl
:
kubectl apply -f previewConfig.yaml
This configuration component can then be referenced in any application by modifying the application’s configuration to reference that specific configuration component via the dapr.io/config
element. For example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
labels:
app: node
spec:
replicas: 1
selector:
matchLabels:
app: node
template:
metadata:
labels:
app: node
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/config: "featureconfig"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
Next steps
Configuration schema11 - How-To: Configure Environment Variables from Secrets for Dapr sidecar
In special cases, the Dapr sidecar needs an environment variable injected into it. This use case may be required by a component, a 3rd party library, or a module that uses environment variables to configure the said component or customize its behavior. This can be useful for both production and non-production environments.
Overview
In Dapr 1.15, the new dapr.io/env-from-secret
annotation was introduced, similar to dapr.io/env
.
With this annotation, you can inject an environment variable into the Dapr sidecar, with a value from a secret.
Annotation format
The values of this annotation are formatted like so:
- Single key secret:
<ENV_VAR_NAME>=<SECRET_NAME>
- Multi key/value secret:
<ENV_VAR_NAME>=<SECRET_NAME>:<SECRET_KEY>
<ENV_VAR_NAME>
is required to follow the C_IDENTIFIER
format and captured by the [A-Za-z_][A-Za-z0-9_]*
regex:
- Must start with a letter or underscore
- The rest of the identifier contains letters, digits, or underscores
The name
field is required due to the restriction of the secretKeyRef
, so both name
and key
must be set. Learn more from the “env.valueFrom.secretKeyRef.name” section in this Kubernetes documentation.
In this case, Dapr sets both to the same value.
Configuring single key secret environment variable
In the following example, the dapr.io/env-from-secret
annotation is added to the Deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
spec:
template:
metadata:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/env-from-secret: "AUTH_TOKEN=auth-headers-secret"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
The dapr.io/env-from-secret
annotation with a value of "AUTH_TOKEN=auth-headers-secret"
is injected as:
env:
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: auth-headers-secret
key: auth-headers-secret
This requires the secret to have both name
and key
fields with the same value, “auth-headers-secret”.
Example secret
Note: The following example is for demo purposes only. It’s not recommended to store secrets in plain text.
apiVersion: v1
kind: Secret
metadata:
name: auth-headers-secret
type: Opaque
stringData:
auth-headers-secret: "AUTH=mykey"
Configuring multi-key secret environment variable
In the following example, the dapr.io/env-from-secret
annotation is added to the Deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
spec:
template:
metadata:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/env-from-secret: "AUTH_TOKEN=auth-headers-secret:auth-header-value"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
The dapr.io/env-from-secret
annotation with a value of "AUTH_TOKEN=auth-headers-secret:auth-header-value"
is injected as:
env:
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: auth-headers-secret
key: auth-header-value
Example secret
Note: The following example is for demo purposes only. It’s not recommended to store secrets in plain text.
apiVersion: v1
kind: Secret
metadata:
name: auth-headers-secret
type: Opaque
stringData:
auth-header-value: "AUTH=mykey"