Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 61 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,65 @@
# OpenStack Keystone in Rust

Successor to the OpenStack Keystone written in Rust.

This project aims at implementing OpenStack Identity service using the Rust as
the programming language. It focuses on implementing v4 API, while certain set
of the v3 API is also going to be implemented making transition easier.

As of now it can be easily deployed in parallel to the python Keystone just by
forwarding v3 APIs to the python Keystone and v4 APIs to the rust
implementation.
The legacy Keystone identity service (written in Python and maintained upstream
by OpenStack Foundation) has served the OpenStack ecosystem reliably for years.
It handles authentication, authorization, token issuance, service catalog,
project/tenant management, and federation services across thousands of
deployments. However, as we embarked on adding next-generation identity
features—such as native WebAuthn (“passkeys”), modern federation flows, direct
OIDC support, JWT login, workload authorization, restricted tokens and
service-accounts—it became clear that certain design and performance
limitations of the Python codebase would hamper efficient implementation of
these new features.

Consequently, we initiated a project termed “Keystone-NG”: a Rust-based
component that augments rather than fully replaces the existing Keystone
service. The original plan was to implement only the new feature-set in Rust
and route those new API paths to the Rust component, while keeping the core
Python Keystone service in place for existing users and workflows.

As development progressed, however, the breadth of new functionality (and the
opportunity to revisit some of the existing limitations) led to a partial
re-implementation of certain core identity flows in Rust. This allows us to
benefit from Rust’s memory safety, concurrency model, performance, and modern
tooling, while still preserving the upstream Keystone Python service as the
canonical “master” identity service, routing only the new endpoints and
capabilities through the Rust component.

In practice, this architecture means:

- The upstream Python Keystone remains the main identity interface, preserving
backward compatibility, integration with other OpenStack services, existing
user workflows, catalogs, policies and plugins.

- The Rust “Keystone-NG” component handles new functionality, specifically:

- Native WebAuthN (passkeys) support for passwordless / phishing-resistant MFA

- A reworked federation service, enabling modern identity brokering and
advanced federation semantics OIDC (OpenID Connect) Direct in Keystone,
enabling Keystone to act as an OIDC Provider or integrate with external
OIDC identity providers natively JWT login flows, enabling stateless,
compact tokens suitable for new micro-services, CLI, SDK, and
workload-to-workload scenarios

- Workload Authorization, designed for service-to-service authorization in
cloud native contexts (not just human users)

- Restricted Tokens and Service Accounts, which allow fine-grained,
limited‐scope credentials for automation, agents, and service accounts,
with explicit constraints and expiry

By routing only the new flows through the Rust component we preserve the
stability and ecosystem compatibility of Keystone, while enabling a
forward-looking identity architecture. Over time, additional identity flows
may be migrated or refactored into the Rust component as needed, but our
current objective is to retain the existing Keystone Python implementation as
the trusted, mature baseline and incrementally build the “Keystone-NG” Rust
service as the complement.

We believe this approach allows the best of both worlds: the trusted maturity
of Keystone’s Python code-base, combined with the modern, high-safety,
high-performance capabilities of Rust where they matter most.

## Config

Expand All @@ -34,7 +85,7 @@ throughput (RPS).

For every PR load test suite is being executed. It is absolutely clear that the
Rust implementation currently misses certain things original Keystone doe, but
the gap is being closed over the time. However test shows difference of factor
the gap is being closed over the time. However test shows difference of factor
**10-100** which is already remarkable. New tests will appear to have a more
thorough coverage of the exposed API.

Expand Down
2 changes: 1 addition & 1 deletion doc/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ create-missing = false

[output.html.fold]
enable = true
level = 2
level = 1

[preprocessor]

Expand Down
23 changes: 17 additions & 6 deletions doc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,26 @@

---

[Architecture](./architecture.md)
[Policy enforcement](./policy.md)
# Keystone internals

* [Architecture](./architecture.md)
* [Architecture decision records](adr/index.md)
* [Record architecture decisions](adr/0001-record-architecture-decisions.md)
* [Open Policy Agent](adr/0002-open-policy-agent.md)
* [Sea ORM](adr/0003-sea-orm.md)
* [v4 API](adr/0004-v4-api.md)
* [Passkey Auth](adr/0005-auth-passkey.md)
* [Federation IDP](adr/0006-federation-idp.md)
* [Federation Mapping](adr/0007-federation-mapping.md)
* [Workload Federation](adr/0008-workload-federation.md)
* [Policy enforcement](./policy.md)
* [Fernet token]()
* [Token payloads]()

---

# Features

- [Federation](./federation.md)
- [Oidc RP mode](./oidc.md)
- [JWT](./jwt.md)
Expand All @@ -18,8 +33,4 @@

---

[Architecture Decision Records](adr/index.md)

---

[Performance comparison](./performance.md)
2 changes: 1 addition & 1 deletion doc/src/adr/0002-open-policy-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Engine.

## Consequences

- Policy evaluation requires external service (OPA) to be running.
- Policy evaluation requires external service (OPA) to be running.

- When covering existing functionality of the python Keystone policies SHOULD
be converted as is and do not introduce a changed flow.
4 changes: 2 additions & 2 deletions doc/src/adr/0004-v4-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ New authentication workflows cannot be covered with the existing Keystone v3
API. As such it is required to add new API methods and eventually change the
existing. As such not to break compatibility and provide a relatively easy way
to route the traffic allowing both project (python and rust) to co-exist a new
v4 API version should be introduced.
v4 API version should be introduced.

## Decision

- All new auth methods MUST be implemented in v4.
- All new auth methods MUST be implemented in v4.

- Known issues with the v3 API SHOULD be addressed in the v3.

Expand Down
3 changes: 1 addition & 2 deletions doc/src/adr/0005-auth-passkey.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Nowadays password-less authentication becomes standard. In OpenStack it is at
the moment not implemented whether on the API level (for the CLI) nor on the UI.

[Webauthn](https://webauthn.io/) is a well accepted standard for implementing
password-less authentication with the help of hardware or software
password-less authentication with the help of hardware or software
authenticators. Keystone should implement support for new authentication methods
relying on the webauthn.

Expand Down Expand Up @@ -40,4 +40,3 @@ state.

New authentication method allows users to get valid token without requiring user
to pass any secrets on the wire. Overall security of the system is increased.

3 changes: 1 addition & 2 deletions doc/src/adr/0007-federation-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ for Keystone.

"Mapping" (attribute mapping) MUST describe how the information from OIDC
claims need to be translated into the Keystone data model. It MUST also describe
user defined bounds to allow use restriction.
user defined bounds to allow use restriction.

When `domain_id` is not being set on the IdP level it MUST be defined either on
the mapping entry, or the mapping MUST define `domain_id_claim` to extract the
Expand All @@ -38,4 +38,3 @@ used.

- Mappings MUST be configured carefully to prevent login of users across the
domain borders. `bound_xxx` should be used extensively to guard this.

2 changes: 1 addition & 1 deletion doc/src/adr/0008-workload-federation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ platform which the service provider can trust. This is very similar (and
technically relates) to the OIDC standard.

In the JWT flow the "user" is exchanging a JWT token issued by the trusted
IdP for a Keystone token. This authentication response includes a token and a
IdP for a Keystone token. This authentication response includes a token and a
service catalog to provide a known OpenStack usage scenario.

## Decision
Expand Down
12 changes: 3 additions & 9 deletions doc/src/adr/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
# Architecture decision records
# Architecture Decision Records

* [1. Record architecture decisions](0001-record-architecture-decisions.md)
* [2. Open Policy Agent](0002-open-policy-agent.md)
* [3. Sea ORM](0003-sea-orm.md)
* [4. v4 API](0004-v4-api.md)
* [5. Passkey Auth](0005-auth-passkey.md)
* [6. Federation IDP](0006-federation-idp.md)
* [7. Federation Mapping](0007-federation-mapping.md)
* [8. Workload Federation](0008-workload-federation.md)
Keystone project uses Architecture Decision Records to describe why the software
is built how it is built.
70 changes: 56 additions & 14 deletions doc/src/intro.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,65 @@
# OpenStack Keystone in Rust

What happens if OpenStack Keystone would be rewritten in Rust? Is it possible?
How complex is it? Which improvements are possible?
The legacy Keystone identity service (written in Python and maintained upstream
by OpenStack Foundation) has served the OpenStack ecosystem reliably for years.
It handles authentication, authorization, token issuance, service catalog,
project/tenant management, and federation services across thousands of
deployments. However, as we embarked on adding next-generation identity
features—such as native WebAuthn (“passkeys”), modern federation flows, direct
OIDC support, JWT login, workload authorization, restricted tokens and
service-accounts—it became clear that certain design and performance
limitations of the Python codebase would hamper efficient implementation of
these new features.

This project exists to answer this questions.
Consequently, we initiated a project termed “Keystone-NG”: a Rust-based
component that augments rather than fully replaces the existing Keystone
service. The original plan was to implement only the new feature-set in Rust
and route those new API paths to the Rust component, while keeping the core
Python Keystone service in place for existing users and workflows.

Primary target of the project is to implement a Rust library implementing
Keystone functionality to be able to split a Keystone monolith into smaller
pieces (similar to the microservices). Once this is done, adding an API is
becoming also pretty simple.
As development progressed, however, the breadth of new functionality (and the
opportunity to revisit some of the existing limitations) led to a partial
re-implementation of certain core identity flows in Rust. This allows us to
benefit from Rust’s memory safety, concurrency model, performance, and modern
tooling, while still preserving the upstream Keystone Python service as the
canonical “master” identity service, routing only the new endpoints and
capabilities through the Rust component.

It targets deploying Python and Rust implementation in parallel and do request
routing on the web server level to get the speed and security of Rust
implementation while keeping functions not implemented (yet) being served by the
original Keystone. This approach also makes it possible to deploy Rust
implementation in parallel to a much older version of Keystone giving
possibility for the operators to enable new features while still using older
version of Keystone (whatever the reason for that is).
In practice, this architecture means:

- The upstream Python Keystone remains the main identity interface, preserving
backward compatibility, integration with other OpenStack services, existing
user workflows, catalogs, policies and plugins.

- The Rust “Keystone-NG” component handles new functionality, specifically:

- Native WebAuthN (passkeys) support for passwordless / phishing-resistant MFA

- A reworked federation service, enabling modern identity brokering and
advanced federation semantics OIDC (OpenID Connect) Direct in Keystone,
enabling Keystone to act as an OIDC Provider or integrate with external
OIDC identity providers natively JWT login flows, enabling stateless,
compact tokens suitable for new micro-services, CLI, SDK, and
workload-to-workload scenarios

- Workload Authorization, designed for service-to-service authorization in
cloud native contexts (not just human users)

- Restricted Tokens and Service Accounts, which allow fine-grained,
limited‐scope credentials for automation, agents, and service accounts,
with explicit constraints and expiry

By routing only the new flows through the Rust component we preserve the
stability and ecosystem compatibility of Keystone, while enabling a
forward-looking identity architecture. Over time, additional identity flows
may be migrated or refactored into the Rust component as needed, but our
current objective is to retain the existing Keystone Python implementation as
the trusted, mature baseline and incrementally build the “Keystone-NG” Rust
service as the complement.

We believe this approach allows the best of both worlds: the trusted maturity
of Keystone’s Python code-base, combined with the modern, high-safety,
high-performance capabilities of Rust where they matter most.

## Compatibility

Expand Down
2 changes: 1 addition & 1 deletion doc/src/oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ be set. For the sake of example simplicity domains are modelled as user groups
in Keycloak. Such group gets the attribute with the value of the domain_id.
Users belonging to such group inherit this attribute automatically.
Alternatively every user may be extended with the domain_id attribute
individually.
individually.

Keycloak can be used as an Identity provider by the Keystone.

Expand Down
Loading
Loading