Skip to content

Introduce AuthToken rotation and session auth support #1380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2023

Conversation

injectives
Copy link
Contributor

@injectives injectives commented Feb 20, 2023

The main feature of this update is the support for AuthToken rotation, which might also be referred to as a refresh or re-auth. In practice, it allows replacing the current token with a new token during the driver's lifetime.

The main objective of this feature is to allow token rotation for the same identity. As such, it is not intended for a change of identity.

A new type called AuthTokenManager has the following 2 primary responsibilities:

  • supplying a valid token, which may be one of the following:
    • the current token
    • a new token, which instructs the driver to use the new token
  • handling a token expiration failure that originates from the server if it determines the current token to be expired (a timely rotation should generally reduce the likelihood of this happening)

The driver does not make judgements on whether the current AuthToken should be updated. Instead, it calls the AuthTokenManager to check if the provided token is the same as the currently used token and takes action if not. The driver reserves the right to call the manager as often as it deems necessary. The manager implementations must be thread-safe and non-blocking for caller threads. For instance, IO operations must not be done on the calling thread.

The GraphDatabase class has been updated to include a set of new methods that accept the AuthTokenManager.

An example of the driver instantiation:

var manager = // the manager implementation
var driver = GraphDatabase.driver(uri, manager);

The token rotation benefits from the new Bolt 5.1 version, but works on previous Bolt versions at the expence of replacing existing connections with new connections.

An expiration based AuthTokenManager implementation is available via a new AuthTokenManagers factory. It manages AuthToken instances that come with a UTC expiration timestamp and calls a new token supplier, which is provided by the user, when a new token is required.

An example of the expiration based manager instantiation:

var manager = AuthTokenManagers.expirationBased(() -> {
  var token = // get new token logic
  return token.expiringAt(timestamp); // a new method on AuthToken introduced for the supplied expiration based AuthTokenManager implementation
});

The new LOGOFF and LOGON Bolt protocol messages allow for auth management on active Bolt connections and are used by the features in this update.

In addition to the token rotation support, this update also includes support for setting a static AuthToken instance on the driver session level.

Unlike the rotation feature, this feature may be used for an identity change. As such, it might be referred to as user switching.

It requires a minimum Bolt 5.1 version.

The Driver interface has 2 new session methods that accept an AuthToken instance.

A basic example:

var token = AuthTokens.bearer("token");
var session = driver.session(Session.class, token);

The Driver includes a new method that checks whether the session auth is supported.

The implementation assumes all servers to be at the same version.

Sample usage:

var supports = driver.supportsSessionAuth();

The Driver includes a new method that verifies a given AuthToken instance by communicating with the server.

It requires a minimum Bolt 5.1 version.

Sample usage:

var token = AuthTokens.bearer("token");
var successful = driver.verifyAuthentication(token);

There are 2 new exceptions:

  • AuthTokenManagerExecutionException - Indicates that the AuthTokenManager execution has lead to an unexpected result. This includes invalid results and errors.
  • TokenExpiredRetryableException - Indicates that the token supplied by the AuthTokenManager has been deemed as expired by the server. This is a retryable variant of the TokenExpiredException used when the driver has an explicit AuthTokenManager that might supply a new token following this failure. If driver is instantiated with the static AuthToken, the TokenExpiredException will be used instead.

@injectives injectives marked this pull request as draft February 20, 2023 15:14
@injectives injectives force-pushed the feature/reauth branch 7 times, most recently from e8bed2a to 14e47b3 Compare February 24, 2023 13:37
@injectives injectives force-pushed the feature/reauth branch 2 times, most recently from fe04cec to 8b1957c Compare March 1, 2023 19:10
@injectives injectives changed the title Auth Introduce change of AuthToken support Mar 1, 2023
@injectives injectives requested review from michael-simons and gjmwoods and removed request for michael-simons and gjmwoods March 1, 2023 19:27
@injectives injectives force-pushed the feature/reauth branch 7 times, most recently from a699004 to 5ab78a9 Compare March 2, 2023 18:23
@injectives injectives changed the title Introduce change of AuthToken support Introduce AuthToken rotation support Mar 2, 2023
@injectives injectives force-pushed the feature/reauth branch 3 times, most recently from 5210782 to 4298ad7 Compare March 2, 2023 18:38
@injectives injectives changed the title Introduce AuthToken rotation support Introduce AuthTokenManager and Session auth Mar 2, 2023
@injectives injectives changed the title Introduce AuthTokenManager and Session auth Introduce AuthTokenManager and session auth Mar 2, 2023
@injectives injectives force-pushed the feature/reauth branch 2 times, most recently from b6b85b2 to c56341e Compare March 2, 2023 18:58
@injectives injectives force-pushed the feature/reauth branch 3 times, most recently from b4ab5f5 to dcb534f Compare March 9, 2023 22:22
@injectives injectives force-pushed the feature/reauth branch 6 times, most recently from da5b47d to e87fd83 Compare April 3, 2023 14:56
@injectives
Copy link
Contributor Author

What I don't like is the naming. Temporal can be anything. While it is better than Renewable, it doesn't capture the essence of wrt it expires. It is a mouthful, but ExpiringToken or TokenWIthExpirationDate would give a very clear indication of what this actually is.

@michael-simons, thanks a lot for the review and for the kind comment.

As you might be aware, there has been a team discussion and it has been decided to go with AuthTokenAndExpiration, which hopefully is a better name.

@injectives
Copy link
Contributor Author

Also apreciate the detailed PR comment, especially with how much the ADR has grown in size.

Just some minor initial comments on the surface parts.

@gjmwoods many thanks for the review and for the kind comment.

The comments have been addressed.

@injectives injectives requested a review from gjmwoods April 3, 2023 15:10
@injectives injectives force-pushed the feature/reauth branch 7 times, most recently from 79aa505 to dca7a58 Compare April 6, 2023 09:47
@injectives injectives marked this pull request as ready for review April 6, 2023 11:13
The main feature of this update is the support for `AuthToken` rotation, which might also be referred to as a refresh or re-auth. In practice, it allows replacing the current token with a new token during the driver's lifetime.

The main objective of this feature is to allow token rotation for the same identity. As such, it is not intended for a change of identity.

A new type called `AuthTokenManager` has the following 2 primary responsibilities:
- supplying a valid token, which may be one of the following:
  - the current token
  - a new token, which instructs the driver to use the new token
- handling a token expiration failure that originates from the server if it determines the current token to be expired (a timely rotation should generally reduce the likelihood of this happening)

The driver does not make judgements on whether the current `AuthToken` should be updated. Instead, it calls the `AuthTokenManager` to check if the provided token is the same as the currently used token and takes action if not. The driver reserves the right to call the manager as often as it deems necessary. The manager implementations must be thread-safe and non-blocking for caller threads. For instance, IO operations must not be done on the calling thread.

The `GraphDatabase` class has been updated to include a set of new methods that accept the `AuthTokenManager`.

An example of the driver instantiation:
```java
var manager = // the manager implementation
var driver = GraphDatabase.driver(uri, manager);
```

The token rotation benefits from the new Bolt 5.1 version, but works on previous Bolt versions at the expence of replacing existing connections with new connections.

An expiration based `AuthTokenManager` implementation is available via a new `AuthTokenManagers` factory. It manages `AuthToken` instances that come with a UTC expiration timestamp and calls a new token supplier, which is provided by the user, when a new token is required.

An example of the expiration based manager instantiation:
```java
var manager = AuthTokenManagers.expirationBased(() -> {
  var token = // get new token logic
  return token.expiringAt(timestamp); // a new method on AuthToken introduced for the supplied expiration based AuthTokenManager implementation
});
```

The new `LOGOFF` and `LOGON` Bolt protocol messages allow for auth management on active Bolt connections and are used by the features in this update.

In addition to the token rotation support, this update also includes support for setting a static `AuthToken` instance on the driver session level.

Unlike the rotation feature, this feature may be used for an identity change. As such, it might be referred to as user switching.

It requires a minimum Bolt 5.1 version.

The `Driver` interface has 2 new `session` methods that accept an `AuthToken` instance.

A basic example:
```java
var token = AuthTokens.bearer("token");
var session = driver.session(Session.class, token);
```

The `Driver` includes a new method that checks whether the session auth is supported.

The implementation assumes all servers to be at the same version.

Sample usage:
```java
var supports = driver.supportsSessionAuth();
```

The `Driver` includes a new method that verifies a given `AuthToken` instance by communicating with the server.

It requires a minimum Bolt 5.1 version.

Sample usage:
```java
var token = AuthTokens.bearer("token");
var successful = driver.verifyAuthentication(token);
```

There are 2 new exceptions:
- `AuthTokenManagerExecutionException` - Indicates that the `AuthTokenManager` execution has lead to an unexpected result. This includes invalid results and errors.
- `TokenExpiredRetryableException` - Indicates that the token supplied by the `AuthTokenManager` has been deemed as expired by the server. This is a retryable variant of the `TokenExpiredException` used when the driver has an explicit `AuthTokenManager` that might supply a new token following this failure. If driver is instantiated with the static `AuthToken`, the `TokenExpiredException` will be used instead.
@injectives injectives removed on hold Work has temporarily been suspended discussion labels Apr 12, 2023
@injectives injectives merged commit 8a73fc9 into neo4j:5.0 Apr 12, 2023
@injectives injectives deleted the feature/reauth branch April 12, 2023 13:29
injectives added a commit to injectives/neo4j-java-driver that referenced this pull request Jun 15, 2023
The main feature of this update is the support for `AuthToken` rotation, which might also be referred to as a refresh or re-auth. In practice, it allows replacing the current token with a new token during the driver's lifetime.

The main objective of this feature is to allow token rotation for the same identity. As such, it is not intended for a change of identity.

A new type called `AuthTokenManager` has the following 2 primary responsibilities:
- supplying a valid token, which may be one of the following:
  - the current token
  - a new token, which instructs the driver to use the new token
- handling a token expiration failure that originates from the server if it determines the current token to be expired (a timely rotation should generally reduce the likelihood of this happening)

The driver does not make judgements on whether the current `AuthToken` should be updated. Instead, it calls the `AuthTokenManager` to check if the provided token is the same as the currently used token and takes action if not. The driver reserves the right to call the manager as often as it deems necessary. The manager implementations must be thread-safe and non-blocking for caller threads. For instance, IO operations must not be done on the calling thread.

The `GraphDatabase` class has been updated to include a set of new methods that accept the `AuthTokenManager`.

An example of the driver instantiation:
```java
var manager = // the manager implementation
var driver = GraphDatabase.driver(uri, manager);
```

The token rotation benefits from the new Bolt 5.1 version, but works on previous Bolt versions at the expence of replacing existing connections with new connections.

An expiration based `AuthTokenManager` implementation is available via a new `AuthTokenManagers` factory. It manages `AuthToken` instances that come with a UTC expiration timestamp and calls a new token supplier, which is provided by the user, when a new token is required.

An example of the expiration based manager instantiation:
```java
var manager = AuthTokenManagers.expirationBased(() -> {
  var token = // get new token logic
  return token.expiringAt(timestamp); // a new method on AuthToken introduced for the supplied expiration based AuthTokenManager implementation
});
```

The new `LOGOFF` and `LOGON` Bolt protocol messages allow for auth management on active Bolt connections and are used by the features in this update.

In addition to the token rotation support, this update also includes support for setting a static `AuthToken` instance on the driver session level.

Unlike the rotation feature, this feature may be used for an identity change. As such, it might be referred to as user switching.

It requires a minimum Bolt 5.1 version.

The `Driver` interface has 2 new `session` methods that accept an `AuthToken` instance.

A basic example:
```java
var token = AuthTokens.bearer("token");
var session = driver.session(Session.class, token);
```

The `Driver` includes a new method that checks whether the session auth is supported.

The implementation assumes all servers to be at the same version.

Sample usage:
```java
var supports = driver.supportsSessionAuth();
```

The `Driver` includes a new method that verifies a given `AuthToken` instance by communicating with the server.

It requires a minimum Bolt 5.1 version.

Sample usage:
```java
var token = AuthTokens.bearer("token");
var successful = driver.verifyAuthentication(token);
```

There are 2 new exceptions:
- `AuthTokenManagerExecutionException` - Indicates that the `AuthTokenManager` execution has lead to an unexpected result. This includes invalid results and errors.
- `TokenExpiredRetryableException` - Indicates that the token supplied by the `AuthTokenManager` has been deemed as expired by the server. This is a retryable variant of the `TokenExpiredException` used when the driver has an explicit `AuthTokenManager` that might supply a new token following this failure. If driver is instantiated with the static `AuthToken`, the `TokenExpiredException` will be used instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Neo4j credential rotation during application runtime
4 participants