API key delegated permissions
Unify access rules between regular users and API keys by switching to a model where API keys are delegated a subset of their owning user's permissions.
The current API key system was designed for ingestion management only, with limited read capability added on later, and shows a lot of quirks because of it.
- API key tokens are treated primarily as identifiers rather than as credentials
- It's not possible to create an API key that can perform admin-level tasks at all
- API keys can only be assigned all-or-nothing user-level access, where more restricted access may be desirable
- Users can't create API keys to perform tasks on their behalf that they're otherwise permitted to perform themselves
In Seq 5 we have the opportunity to modernize and redesign API keys, and to overhaul the underlying permissions model to better support them.
The proposal has three major parts:
- User roles and permissions will be introduced so that API keys can have fine-grained user permissions delegated to them
- API keys will gain the concept of an owner - the user who delegates their permissions to the API key
- API key storage will switch to a hashed-credentials model
The summaries in this section highlight how the major use cases for API keys will be achieved in the new version.
API keys for application log ingestion
It's anticipated that API keys for application log ingestion will continue to be created and maintained by a system administrator, as shared (non-personal) API keys. This will prevent interruption of application logging when users come and go.
A user may still create a personal API key and use it to ingest log events if they wish - this essentially provides "self-service" API key creation. Using shared keys for ingestion will be encouraged but not required.
API keys created for ingestion purposes will have the
Ingest permission assigned: this will be selected by default when creating a new shared API key, as it is by far the most common use case.
API keys for reporting/integration
Again, for important reporting and integration tasks, shared API keys created by an administrator will be recommended. However, developers testing an integration or performing analysis may often self-serve API keys for this purpose.
Most reporting and integration tasks should be achievable using an API key with only
Ingest permissions - many integration scenarios are possible without requiring a
Write API key.
API keys for scripted system setup and administration
API keys can be used for scripted setup in essentially the same manner as for reporting and integration, but with the
Setup permissions delegated to them.
Controlling ingestion rate per API key
When an administrative user browses Settings > API keys, by default only shared keys will be shown. By selecting the new Show personal API keys checkbox, the details of API keys owned by all users will be included, showing the ingestion rate for personal as well as shared keys.
Note that this will not reveal the tokens associated with personal API keys, as these will have been hashed and therefore will not be retrievable from storage.
Administrators will be able to view and revoke personal API keys; however, to edit the personal API key of another user, the administrator must at that point make the API key shared, i.e., dissociated from the original owner. This ensures that administrative changes to otherwise personally-controlled entities is readily apparent.
Roles & permissions
In order for users to delegate permissions to API keys, we must be able to associate permissions with a user. This will be achiveved by assigning to a user zero or more roles; each role will confer zero or more permissions. The permissions associated with a user's roles are available for delegation to API keys.
Initially, we'll start with a limited set of broad permissions, to simplify migration from Seq 4.x; later versions will extend this set by adding and splitting permissions:
- Setup - access to administrative features of Seq, management of other users, app installation, backups
- Write - lower-privileged write-access to signals, alerts, preferences etc.
- Read - query events, dashboards, signals, app instances
- Ingest - write events to the stream
Permissions are hard-coded into the application.
A role associates a user with a set of permissions. The permissions held by a user are the aggregate set of all roles held by the user. Intially there will be the following built-in, fixed roles:
- Administrator - Setup + Write + Read + Ingest (+ Public)
- User - Write + Read + Ingest (+ Public)
- Ingestion Key - Ingest (+ Public)
Again, these are chosen to simplify forward migration, but future versions can extend this set and allow new roles to be defined and customized.
API key creation
This proposal introduces the notion of an owner of an API key.
- General system-level keys, created in Settings > API keys will have a
nullowner, and be visible to/managed by, any user with the
- Personal API keys, created via the (Username) > API keys preferences panel, will be associated with their owning user for their lifetime
When an API key is created, the set of permissions held by the current user will be presented in a checkbox-list; the user must choose at least one of the permissions to associat with the API key.
Note, this does not grant the specified permissions to the key directly - the permissions are only delegated, so that if the user's role changes or their permissions are revoked through some other action, the API key will no longer have the permissions in question.
API key storage
When an API key is created, its token will be presented once only; the token will be stored using a cryptographic hash (likely PBKDF2) so that it cannot be retrieved from the server at a later date.
To simplify management, a four- or six-character prefix will be added to the token and stored in plain text. This will enable approximate identification of API keys given a full token and the list of known prefixes in the API keys management screen.
Migration of existing API keys
It would be nice to move existing API keys to the hashed storage model automatically, however it's likely this will cause API key information to be lost unexpectedly by customers who rely on being able to look up API keys in Seq by token.
Instead, we'll migrate keys as-is, retainig a plain-text token, but use the hashed storage scheme for new keys when they are created. A similar strategy has been employed by other projects (AWS, NuGet.org) when the same change was introduced elsewhere.
Seq.Api client changes
The Seq.Api library currently uses API keys for authentication. It's expected that following this change, API-key authenticated access from the client library will continue to work unchanged, and new capabilities enabled by the broader possible permissions will just work.
When used for API key and user provisioning, the client library and apps that use it will need to be updated:
RoleEntitywill need to be added, along with a
RoleIdscollection, and will have
DelegatedPermissionscollection, and will have
There will be some slight churn introduced by this change, particularly:
- Customers depending on Seq as a readable store for API keys will need to introduce/use an external credential management system to store them
- Scripts/applications that use the Seq HTTP API for user account and API key creation and management will need to be updated to use role ids rather than Boolean
Roles: A further possible role, "System Adminstrator", may exist in reality - this would be the role of the person with full access to the underlying machine who would install/maintain Seq from e.g. the server's local shell. This role is not modelled because it sits outside the Seq application, but it's worth keeping in mind that the Administrator role within Seq may not correspond to a system administration role on the machine.
Current API key model documentation: https://docs.getseq.net/docs/api-keys
C# HTTP API client: https://github.com/datalust/seq-api