API key authentication
Status: Draft
Sponsor User: IBM
Date of Submission: Apr 22, 2025
Submitted by: Michał Krok (michal.krok@ibm.com)
Affiliation(s): IBM
<Please fill out the above fields, and the Overview, Design and User Experience sections below for an initial review of the proposed feature.>
Scope and Signoff: primarily Exchange, CLI
Overview
<Briefly describe the problem being solved, not how the problem is solved, just focus on the problem. Think about why the feature is needed, and what is the relevant context to understand the problem.>
This is a feature request to add support for API key authentication. Currently the OpenHorizon only supports username/password authentication. This creates issues for automated use cases like scripts or system integrations, where storing and using full user credentials isn’t ideal. API key support would provide a simpler and safer way to authenticate in these scenarios.
User Experience
<Describe which user roles are related to the problem AND the solution, e.g. admin, deployer, node owner, etc. If you need to define a new role in your design, make that very clear. Remember this is about what a user is thinking when interacting with the system before and after this design change. This section is not about a UI, it's more abstract than that. This section should explain all the aspects of the proposed feature that will surface to users.>
Api key management
API keys are created via dedicated endpoints in Exchange API or corresponding commands in HZN CLI.
Any authenticated user can create and manage their own API keys.
The owner of the API key has a full control over it; ownership is non-transitive.
The privileges required to view/manage API keys are the same as these used to view/manage users.
This means that the admins that have ability to view the users within the organization can list their API keys. And if they have ability to modify the change the user password they can create/delete the API keys on their behalf.
API keys are immutable – after creation the authorized user can only view the API key metadata or delete the API key.
The API key value is presented to the user only upon creation – the user will need to safely store this value on their side for future use.
Each user can possess zero, one or more API keys.
API key usage
Users use API keys for interaction with HZN CLI or Exchange API the same way they use username:password credentials. In place of username there is used apikey keyword and API key value is passed instead of password. So, authentications string takes form of apikey:<API_KEY_VALUE>.
Design
<Describe how the problem is fixed. Include all affected components. Include diagrams for clarity. This should be the longest section in the document. Use the sections below to call out specifics related to each aspect of the overall system, and refer back to this section for context. Provide links to any relevant external information.>
API key value is a UUID v4 and it is generated internally and exposed only upon creation.
It is hashed immediately and stored in hashed form in newly added APIKEY table (schema below).
API keys are immutable (at least in first version).
When a call is made to the Exchange API, Exchange detects if there is apikey keyword passed in place of username in Authorization header and triggers alternative authentication path.
The API key passed in place of password is hashed using the same algorithm.
The hash is used to lookup a record in APIKEY table.
If a match is found the user is inferred from the record.
Exchange validates if the organization specified in the call matches the user’s organization.
If everything is ok call is further authorized based on current privileges of owner of the API key.
Otherwise, the call is rejected.
API keys are not cached to ensure any changes in API key are instantly reflected in all the instances of Exchange.
Creation of users with username apikey is now blocked and treated as invalid request.
Non-user identities (agbots, nodes) will not support API key authentication.
There will be new APIKEY table added to the Exchange database:
ORGANIZATION_ID string // PRIMARY KEY, NOT NULL
APIKEY_ID UUID // PRIMARY KEY, NOT NULL
USER string // FOREIGN KEY, NOT NULL
DESCRIPTION string // NOT NULL
APIKEY_HASH string // NOT NULL
CREATED_AT timestamp // NOT NULL
CREATED_BY string // NOT NULL
MODIFIED_AT timestamp // NOT NULL
MODIFIED_BY string // NOT NULL
UNIQUE INDEX: APIKEY_HASH
INDEX: ORGANIZATION_ID, USER
Command Line Interface
<Describe any changes to the hzn CLI, including before and after command examples for clarity. Include which users will use the changed CLI. This section should flow very naturally from the User Experience section.>
The `hzn exchange user` CLI command is extended with a set of dedicated subcommands:
usage: hzn exchange | ex user <command> [<args> ...]
List and manage users in the Horizon Exchange.
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
-v, --verbose Verbose output.
--dry-run When calling the Horizon or Exchange API, do GETs, but don't do PUTs, POSTs, or DELETEs.
-o, --org=ORG The Horizon exchange organization ID. If not specified, HZN_ORG_ID will be used as a default.
-u, --user-pw=USER:PW Horizon Exchange user credentials to query and create exchange resources. If not specified, HZN_EXCHANGE_USER_AUTH will be used as a default. If you don't prepend it with the user's org, it will automatically be prepended with the -o value. As an alternative to using -o, you can set HZN_ORG_ID with the Horizon exchange organization ID
Commands:
exchange | ex user
create | cr [<flags>] <user> <pw> [<email>]
list | ls [<flags>] [<user>]
remove | rm [<flags>] <user>
setadmin | sa <user> <isadmin>
createkey | ck [<flags>] <user> <description>
getkey | gk [<flags>] <user> <keyid>
removekey | rk [<flags>] <user> <keyid>
Changes:
`hzn exchange user list` subcommand is extended with new `apikeys` attribute (similarly to REST API).
`hzn exchange user createkey` subcommand is added - it executes `POST /v1/orgs/<org>/users/<user>/apikeys` call with payload `{ description: <description> }`
`hzn exchange user getkey` subcommand is added - it executes `GET /v1/orgs/<org>/users/<user>/apikeys/<keyid>`
`hzn exchange user removekey` subcommand is added - it executes `DELETE /v1/orgs/<org>/users/<user>/apikeys/<keyid>`
External Components
<Describe any new or changed interactions with components that are not the agent or the management hub.>
None.
Affected Components
<List all of the internal components (agent, MMS, Exchange, etc) which need to be updated to support the proposed feature. Include a link to the github epic for this feature (and the epic should contain the github issues for each component).>
Exchange
HZN CLI
Security
<Describe any related security aspects of the solution. Think about security of components interacting with each other, users interacting with the system, components interacting with external systems, permissions of users or components>
APIs
<Describe and new/changed/deprecated APIs, including before and after snippets for clarity. Include which components or users will use the APIs.>
There will be added a set of dedicated endpoints to the Exchange API.
POST /v1/orgs/{orgid}/users/{username}/apikeys
Generates API key for given user.
Request:
{
description: string (required)
}
Responses:
· Code 201 (Created)
{
id: UUID,
description: string,
user: string, # owner user's username
value: string # API key value
created_at: timestamp,
created_by: string,
}
· Code 400 (Bad Request) - in case of missing or invalid attribute values or API key identity clash.
· Code 403 (Unauthorized) - when user does not have sufficient privileges (to change the password of this user).
DELETE /v1/orgs/{orgid}/users/{username}/apikeys/{keyid}
Deletes API key with given id.
Responses:
· Code 204 (No Content)
· Code 403 (Unauthorized) - when user does not have sufficient privileges (to change the password of this user).
· Code 404 (Not Found) - when key does not exist.
GET /v1/orgs/{orgid}/users/{username}/apikeys/{keyid}
Returns API key metadata with given id.
Responses:
· Code 200 (OK)
{
id: UUID,
description: string,
user: string, # owner user's username
created_at: timestamp,
created_by: string,
}
· Code 403 (Unauthorized) - when user does not have sufficient privileges (to view this user).
· Code 404 (Not Found) - when key does not exist.
Listing multiple API keys
User fetching endpoints:
GET /v1/orgs/{orgid}/users/{username}
GET /v1/orgs/{orgid}/users
will be extended with the new `apikeys` attribute:
{
users: {
orgid/username: {
password: string,
admin: boolean,
email: string,
lastUpdated: string,
updatedBy: string,
apikeys : [
{
id: UUID,
description: string,
created_at: timestamp,
created_by: string,
},
...
]
}
},
lastIndex: integer
}
Build, Install, Packaging
<Describe any changes to the way any component of the system is built (e.g. agent packages, containers, etc), installed (operators, manual install, batch install, SDO), configured, and deployed (consider the hub and edge nodes).>
There will a schema change in the Exchange database (new table added), so schema migration will need to be performed for OH upgrade path.
Documentation Notes
<Describe the aspects of documentation that will be new/changed/updated. Be sure to indicate if this is new or changed doc, the impacted artifacts (e.g. technical doc, website, etc) and links to the related doc issue(s) in github.>
New documentation article will need to be added to describe API key management and usage.
Documentation describing HZN CLI usage should mention alternative way of authentication.
Documentation of new Exchange APIs
Test
<Summarize new automated tests that need to be added in support of this feature, and describe any special test requirements that you can foresee.>
Regular user can create, fetch, delete their own API keys,
Regular user is NOT allowed to create, fetch, delete API keys of other users,
Admin user can create, fetch, delete their own API keys as well as API keys of users in their organization,
Admin user is NOT allowed to create, fetch, delete API keys of users in other organizations,
User can authenticate to HZN CLI and Exchange API with valid API key,
User is NOT able to authenticate to HZN CLI and Exchange API with deleted API key,
API key reflects the privileges of its owner,
API key value is only exposed upon creation,
apikey cannot be used as username.