From d12b839ef4d367d3fc0031de55b49e1035939cd6 Mon Sep 17 00:00:00 2001 From: Alin Tomescu Date: Fri, 22 Nov 2024 11:49:54 -0500 Subject: [PATCH 1/3] Discuss recovery service for Federated Keyless --- aips/aip-96.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/aips/aip-96.md b/aips/aip-96.md index eb8fc5e7..c4d1ad62 100644 --- a/aips/aip-96.md +++ b/aips/aip-96.md @@ -43,7 +43,7 @@ Currently, a [keyless account’s public key](https://github.com/aptos-foundatio - the identity of the OIDC provider (`iss`) - a commitment, using a *pepper* as a blinding factor, to: - the identity of the user (`sub`) - - the identity of the application (`aud`) + - the identity of the managing application (`aud`) Normally, when verifying keyless TXN signatures for such an account, the validators use the `iss` to look up the OIDC provider’s JWKs in the `0x1::jwks::PatchedJWKs` resource, which acts as the **single source of truth** for an `iss`’s JWKs. @@ -246,7 +246,17 @@ There are several mechanisms to mitigate against this: 1. Test the ZK circuit on the JWTs of IAMs like Auth0, AWS Cognito and Okta and build up a list of supported **federated** OIDC providers. 2. Encourage developers to use the default prover and pepper service in the Aptos SDK, which will allow-list these supported **federated** OIDC providers, thereby preventing developers from using an unsupported one early on. -3. In case of emergency, enable the [leaky mode](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-61.md#warm-up-leaky-signatures-that-reveal-the-users-and-apps-identity), which restores access to the federated keyless account by circumventing the ZK circuit, albeit at the cost of leaking the account’s user (`sub`) and application (`aud`) identity. +3. In case of emergency, enable the [leaky mode](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-61.md#warm-up-leaky-signatures-that-reveal-the-users-and-apps-identity), which restores access to the federated keyless account by circumventing the ZK circuit, albeit at the cost of leaking the account’s user (`sub`) and the managing application's (`aud`) identity. + +### Liveness of managing application + +Recall from [AIP-61](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-61.md#recovery-service) that a keyless account, including a federated one, remains accessible as long as its underlying (1) OIDC account and (2) managing application are both accessible. However, if the managing application goes offline/disappears (e.g., `dapp.xyz` is down), then users are no longer able to sign into their OIDC provider via the application, which means they cannot obtain signed JWTs from the OIDC provider, which in turn means they have no way of proving they own their keyless account. In effect, users would lose access to their keyless account. + +AIP-61 proposed a [recovery service](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-61.md#recovery-service) mode to allow a user to recover from an offline managing application. Specifically, the user can get a JWT from the recovery service (instead of the managing application). This JWT will have the same `iss` and `sub`/`email` fields as the one from the managing application, but would have a different `aud` field: i.e., the recovery service's `aud`. Nonetheless, this JWT can be accepted by Aptos validators as long as the recovery service `aud` is allow-listed in the [Keyless Move module](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-61.md#keyless_accountmove-move-module). + +Unfortunately, this recovery service mode is not likely to work with IAM providers, because their JWTs tend to have tenant-specific `iss` fields, whereas the recovery service mode requires the `iss` to be the same across different applications: i.e., the recovery mode validation logic requires the `iss` and `sub` in the address to match the `iss` and `sub` in the JWT, but does not match the address's `aud` field as long as the JWT's `aud` is allow-listed. + +Although it may be possible to relax this rule by also considering overriding the `iss`, careful investigation would be needed. (For example, JWT's from some IAM providers tend to have `sub` fields of the form `google|722112354821233219`, which already encode the OIDC provider's identity and the user's identity. This could, in principle, be leveraged for recovery.) ### Liveness and security of OIDC provider From 1d922c4585b31bcd2a12e8d749841e5ca3845464 Mon Sep 17 00:00:00 2001 From: Alin Tomescu Date: Fri, 22 Nov 2024 15:08:12 -0500 Subject: [PATCH 2/3] Update aip-96.md --- aips/aip-96.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/aips/aip-96.md b/aips/aip-96.md index c4d1ad62..279ca443 100644 --- a/aips/aip-96.md +++ b/aips/aip-96.md @@ -256,7 +256,7 @@ AIP-61 proposed a [recovery service](https://github.com/aptos-foundation/AIPs/bl Unfortunately, this recovery service mode is not likely to work with IAM providers, because their JWTs tend to have tenant-specific `iss` fields, whereas the recovery service mode requires the `iss` to be the same across different applications: i.e., the recovery mode validation logic requires the `iss` and `sub` in the address to match the `iss` and `sub` in the JWT, but does not match the address's `aud` field as long as the JWT's `aud` is allow-listed. -Although it may be possible to relax this rule by also considering overriding the `iss`, careful investigation would be needed. (For example, JWT's from some IAM providers tend to have `sub` fields of the form `google|722112354821233219`, which already encode the OIDC provider's identity and the user's identity. This could, in principle, be leveraged for recovery.) +Although it may be possible to relax this rule by also considering overriding the `iss`, careful investigation would be needed. (For example, JWT's from [some IAM providers](#example-of-auth0-jwt) tend to have `sub` fields of the form `google|722112354821233219`, which already encode the OIDC provider's identity and the user's identity. This could, in principle, be leveraged for recovery.) ### Liveness and security of OIDC provider @@ -446,3 +446,67 @@ The configuration fetched from the OIDC configuration URL will look like: } ``` +### Example of Auth0 JWT +Header: +``` +{ + "alg": "RS256", + "typ": "JWT", + "kid": "OYryNKGFtFhtHVOd1d_BU" +} +``` + +Payload: +``` +{ + "iss": "https://dev-qtdgjv22jh0v1k7g.us.auth0.com/", + "aud": "dzqI77x0M5YwdOSUx6j25xkdOt8SIxeE", + "iat": 1732301555, + "exp": 1732337555, + "sub": "google-oauth2|113125232581163026067", + "sid": "68dqHtLsHCCzvT7-Nq-NjMZ4dNxjnMxJ", + "nonce": "17657958799152405058321932995845815790037598344919199315814344140953953492891" +} +``` + +### Example of AWS Cognito JWT +Header: +{ + "kid": "ZfQycLUrt9nraKNBwR5rw9tG/VjXIrPQT7sWDZ1DhhQ=", + "alg": "RS256" +} + +Payload: +``` +{ + "custom:key_exists": "0", + "at_hash": "2ZYRkvmSM3PMNzsOZ5o5Tg", + "sub": "cfbc5d30-7626-4fd6-963d-dea685853673", + "cognito:groups": [ + "ap-northeast-1_QUYTOCmLN_Google" + ], + "email_verified": false, + "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_QUYTOCmLN", + "cognito:username": "google_113125232581163026067", + "nonce": "19165884403973631763335615088639144207110394844832509039322243492548588682178", + "origin_jti": "4d7ac6de-073b-494f-a4cb-68b8838308dd", + "aud": "1p110u14jnnd5e98qj55jkvn6h", + "identities": [ + { + "userId": "113125232581163026067", + "providerName": "Google", + "providerType": "Google", + "issuer": null, + "primary": "true", + "dateCreated": "1732301386872" + } + ], + "token_use": "id", + "auth_time": 1732301421, + "custom:expiration": "1732304992", + "exp": 1732305021, + "iat": 1732301421, + "jti": "6ea5ee41-ab5c-4221-b95a-e13e6a4cd2b9", + "email": "aptos.keyless.test@gmail.com" +} +``` From 1a8bd5aad9f47a5008bb5d221e12f8e732c09a9d Mon Sep 17 00:00:00 2001 From: Alin Tomescu Date: Fri, 22 Nov 2024 15:08:48 -0500 Subject: [PATCH 3/3] Update aip-96.md --- aips/aip-96.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aips/aip-96.md b/aips/aip-96.md index 279ca443..bd3914ed 100644 --- a/aips/aip-96.md +++ b/aips/aip-96.md @@ -471,10 +471,12 @@ Payload: ### Example of AWS Cognito JWT Header: +``` { "kid": "ZfQycLUrt9nraKNBwR5rw9tG/VjXIrPQT7sWDZ1DhhQ=", "alg": "RS256" } +``` Payload: ```