Skip to content

Commit af20607

Browse files
jmayclinlrstewartgoatgoose
authored
docs(aws-kms-tls-auth): add readme (#5409)
Co-authored-by: Lindsay Stewart <slindsay@amazon.com> Co-authored-by: Sam Clark <3758302+goatgoose@users.noreply.github.com> Co-authored-by: Lindsay Stewart <stewart.r.lindsay@gmail.com>
1 parent 01ed1e7 commit af20607

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Managing Algorithm & Format Changes.
2+
3+
## Backwards Compatibility: Required
4+
Changes must always be backwards compatible. More specifically, server's must always be able to deserialize earlier versions of PskIdentities, otherwise all of the in-flight communications would fail when an upgrade happens.
5+
6+
## Forward Compatibility: Customer Responsibility
7+
We generally do not promise forwards compatibility: A `0.0.1` V1 enabled server might not be able to handshake with a `0.0.2` V2 enabled client. We will strive to maintain forward compatibility, but if there was ever an upgrade from `AES_256_GCM_SIV` to `AES_512_GCM_SIV`, that would not be forward compatible.
8+
9+
It would be the customer's responsibility to first deploy version 0.0.2 to all servers, and only then would it be safe to enable `PskVersion::V2`. For further
10+
information see the "Versioning" section in the main module docs.
11+
12+
## Example Version Changes
13+
Below are some examples of scenarios that would require a new version change.
14+
- new field: Adding a new field to either PskIdentity or the inner obfuscated fields would require a version change.
15+
- new obfuscation algorithm: switch the obfuscation algorithm from AES-256-GCM-SIV to some other AEAD algorithm.
16+
- new HMAC algorithm: If s2n-tls exposed a new HMAC based on SHA512, we would need
17+
a new PskVersion to take advantage of it.
18+
19+
All of these version changes could be accomplished with some variation of the following strategy.
20+
21+
```rust
22+
struct PskIdentity {
23+
// This is a "rearranged" version of the existing wire format. As long as the
24+
// PskVersion field is first, we can branch on it when parsing.
25+
psk_version: PskVersion,
26+
psk_identity_value: PskIdentityValue
27+
}
28+
29+
enum PskIdentityValue {
30+
V1(PskIdentityV1),
31+
V2(PskIdentityV2),
32+
}
33+
34+
impl PskIdentityValue {
35+
/// version specific logic can be handled in the method
36+
fn deobfuscate_datakey(&self, obfuscation_key: ObfuscationKey) -> Vec<u8> {
37+
match self {
38+
Self::V1(v1_struct) => {
39+
// e.g. assert on the obfuscation_key version or size
40+
}
41+
}
42+
}
43+
}
44+
```
45+
46+
The above code structure would allow the `DecodeValue` and `EncodeValue` traits to work with both variants. Version specific logic can then be handled in the version-specific structs or the `PskIdentityValue` enum.
47+
48+
49+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# aws-kms-tls-auth
2+
3+
This crate provides a way to perform TLS authentication using the AWS Key Management Service (KMS) and Identity and Access Management (IAM). The only supported TLS implementation is currently [s2n-tls](https://github.com/aws/s2n-tls), but if you are interested in support for other TLS implementations please open a [github issue](https://github.com/aws/s2n-tls/issues/new/choose).
4+
5+
## Overview
6+
7+
Clients use the [generateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) API to create a PSK with KMS. The ciphertext datakey is used as the PSK identity, which the server can then [decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html). This PSK exchange is done using the TLS 1.3 out-of-band PSK mechanism. Other TLS protocols are not supported.
8+
9+
## Description
10+
11+
### 0: setup
12+
We start with
13+
- clients: all clients are configured with some IAM role, `client-iam-role`
14+
- servers: all servers are configured with some IAM role, `server-iam-role`.
15+
- kms-key-arn: a [KMS Key Arn](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN), which will look like `arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab`.
16+
- `client-iam-role` must have `kms:GenerateDataKey` permissions on the key
17+
- `server-iam-role` must have `kms:Decrypt` permissions on the key
18+
19+
### 1: client psk generation
20+
When the `PskProvider` is initialized, the client will call the KMS generateDataKey api. This returns both a plaintext data key and a ciphertext datakey. The client will create a PSK using the ciphertext datakey as the PSK identity, and the plaintext datakey as the PSK secret.
21+
22+
### 2: server psk decrypt
23+
The client sends the PSK to the server, which gives it access to the PSK identity (ciphertext datakey). The server then decrypts the ciphertext datakey using KMS, getting back the plaintext datakey which is the actual PSK secret.
24+
25+
At this point the handshake can complete. This results in an mTLS connection between the `client-iam-role` and `server-iam-role`.
26+
27+
### Caching
28+
The server will cache plaintext datakeys. The first connection between a client and server will result in a KMS Decrypt API call, but future TLS handshakes between that same client and server will use the cached key.
29+
30+
### Rotation
31+
The client will automatically rotate its PSK every 24 hours.
32+
33+
## Authentication
34+
When the handshake is complete there is a mutually authenticated connection where
35+
- the client knows that the server has `kms:Decrypt` permissions on the used KMS Key ARN.
36+
- the server knows that the client has `kms:GenerateDataKey` permissions on one of the trusted KMS Key ARNs.
37+
38+
For this reason, it is important to configure the key with minimal permissions. If you only want mTLS to be allowed between `client-iam-role` as a client and `server-iam-role` as a server, then `client-iam-role` must be the only IAM identity with `kms:GenerateDataKey` permissions on the KMS key, and `server-iam-role` must be the only IAM identity with `kms:Decrypt` permissions on the key.
39+
40+
While it is possible to configure multiple client roles with `kms:GenerateDataKey` permissions so the server will trust multiple identities, the server will not authenticate the specific client identity.
41+
42+
**Example**: `client-iam-role-A` and `client-iam-role-B` are the only identities with `kms:GenerateDataKey` permissions on a trusted KMS Key ARN. If the server successfully handshakes then it is talking to `client-iam-role-A` OR `client-iam-role-B`, but it does not know which one.

bindings/rust/aws-kms-tls-auth/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@
5252
//! Note that the [`PskReceiver`] supports lists for both of these items, so
5353
//! zero-downtime migrations are possible. _Example_: if the client fleet wanted
5454
//! to switch from Key A to Key B it would go through the following stages
55-
//! 1. client -> [A], server -> [A]
56-
//! 2. client -> [A], server -> [A, B]
57-
//! 3. client -> [A, B], server -> [A, B]
58-
//! 4. client -> [B], server -> [A, B]
59-
//! 5. client -> [B], server -> [B]
55+
//! 1. clients -> [A] server -> [A]
56+
//! 2. clients -> [A] server -> [A & B]
57+
//! 3. clients -> [A][B], server -> [A & B]
58+
//! 4. clients -> [B], server -> [A & B]
59+
//! 5. clients -> [B], server -> [B]
6060
//!
6161
//! ## Versioning
6262
//!

0 commit comments

Comments
 (0)