Security

EventStoreDB supports basic authentication for HTTP API and TCP calls, and supports access control lists (ACL) for streams.

Authentication and authorization

EventStoreDB supports basic HTTP authentication to internal users. You create and manage these users with the RESTful API or the Admin UI. Read more in the users management guide. Once you have added users, you can use their details with HTTP requests or native client's authorization process.

Alternatively you can also use the 'trusted intermediary' header for externalized authentication that allows you to integrate almost any authentication system with EventStoreDB. Read more about the trusted intermediary header.

If you were to use the wrong user or no user when connecting to EventStoreDB, you receive a 401 Unauthorized response for HTTP API or Exception for native client.

TIP

Remember to change the default password for default users and disable unused users after the cluster setup is complete.

Secure EventStoreDB node

We recommend you connect to EventStoreDB over SSL to encrypt the user information. Read this guide for instructions.

WARNING

Avoid exposing EventStoreDB to the global internet network.

User management

The EventStoreDB .NET client includes helper methods that use the HTTP API to allow for the management of users. This section describes the methods found in the UsersManager class. All methods in this class are asynchronous.

Default users

By default, EventStoreDB has two users admin and ops with the password changeit.

TIP

We recommend you create separate functional account with minimal access rights for any connected application or service.

Default groups

By default, EventStoreDB has two user groups $admins $ops. However, it is possible to create custom groups with the .NET client.

Create UsersManager instance

var hostInfo = Dns.GetHostEntry("localhost");

var manager = new UsersManager(
    new ConsoleLogger(),
    new IPEndPoint(hostInfo.AddressList[0], 2113),
    TimeSpan.FromSeconds(10)
);
1
2
3
4
5
6
7

Resolving the host name may be especially useful if the EventStoreDB Admin UI is not available under loopback address e.g., when container orchestrator assign dynamic DNS based on service name.

Create a user

Creates a user, the credentials for this operation must be a member of the $admins group.

Task CreateUserAsync(
    string login, string fullName, string[] groups, 
    string password, UserCredentials userCredentials = null
);
1
2
3
4

Disable a user

Disables a user, the credentials for this operation must be a member of the $admins group.

Task DisableAsync(string login, UserCredentials userCredentials = null);
1

Enable a User

Enables a user, the credentials for this operation must be a member of the $admins group.

Task EnableAsync(string login, UserCredentials userCredentials = null);
1

Delete a user

Deletes (non-recoverable) a user, the credentials for this operation must be a member of the $admins group. If you prefer this action to be recoverable, disable the user as opposed to deleting the user.

Task DeleteUserAsync(string login, UserCredentials userCredentials = null);
1

List all users

Use this method to get a list of all users in the cluster.

Task<List<UserDetails>> ListAllAsync(UserCredentials userCredentials = null);
1

Get user details

Return the details of the user supplied in user credentials (e.g. the user making the request).

Task<UserDetails> GetCurrentUserAsync(UserCredentials userCredentials);
1

Get details of logged-in user

Task<UserDetails> GetUserAsync(string login, UserCredentials userCredentials);
1

Update user details and groups

Although UsersManager does not have separate methods for idempotent adding/removing user groups it can be extended:

public static class UsersManagerExtensions
{
    public static async Task AddUserToGroupAsync(this UsersManager usersManager, string userLogin, string group, UserCredentials credentials)
    {
        var user   = await usersManager.GetUserAsync(userLogin, credentials);
        var groups = user.Groups.ToList();
        if (groups.Contains(group)) return;

        groups.Add(group);
        await usersManager.UpdateUserAsync(user.LoginName, user.FullName, groups.ToArray(), credentials);
    }

    public static async Task RemoveUserFromGroupAsync(this UsersManager usersManager, string userLogin, string group, UserCredentials credentials)
    {
        var user   = await usersManager.GetUserAsync(userLogin, credentials);
        var groups = user.Groups.ToList();
        if (!groups.Contains(group)) return;

        groups.Remove(group);
        await usersManager.UpdateUserAsync(user.LoginName, user.FullName, groups.ToArray(), credentials);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Task UpdateUserAsync(
    string login, string fullName, string[] groups, 
    UserCredentials userCredentials = null
);
1
2
3
4

Reset user password

Resets the password of a user. The credentials for this operation must be part of the $admins group.

Task ResetPasswordAsync(
    string login, string newPassword, 
    UserCredentials userCredentials = null
);
1
2
3
4

Access control lists

Alongside authentication, EventStoreDB supports per stream configuration of Access Control Lists (ACL). To configure the ACL of a stream go to its head and look for the metadata relationship link to fetch the metadata for the stream.

For more information on the structure of Access Control Lists read Access Control Lists.

ACL example

The ACL below gives writer read and write permission on the stream, while reader has read permission on the stream. Only users in the $admins group can delete the stream or read and write the metadata.

var metadata = StreamMetadata.Build()
    .SetCustomPropertyWithValueAsRawJsonString(
        "customRawJson",
        @"{
            ""$acl"": {
                ""$w"": ""writer"",
                ""$r"": [
                    ""reader"",
                    ""also-reader""
                ],
                ""$d"": ""$admins"",
                ""$mw"": ""$admins"",
                ""$mr"": ""$admins""
            }
        }"
    );
await connection.SetStreamMetadataAsync(
    streamName, 
    ExpectedVersion.Any, 
    metadata, 
    adminCredentials
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Last Updated:
Contributors: Renae Sowald