Skip to content
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

Discuss recovery service for Federated Keyless #536

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
80 changes: 78 additions & 2 deletions aips/aip-96.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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](#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

Expand Down Expand Up @@ -436,3 +446,69 @@ 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": "[email protected]"
}
```