@namespace("keybase.1") protocol UPK { import idl "common.avdl"; enum KeyType { NONE_0, NACL_1, PGP_2 } enum UPK2MinorVersion { V0_0, V1_1, V2_2, V3_3, V4_4, V5_5, V6_6 } record MerkleRootV2 { Seqno seqno; HashMeta hashMeta; } record SigChainLocation { Seqno seqno; SeqType seqType; } record MerkleTreeLocation { UserOrTeamID leaf; SigChainLocation loc; } record SignatureMetadata { KID signingKID; // For an eldest key, the signing KID is itself. MerkleRootV2 prevMerkleRootSigned; Seqno firstAppearedUnverified; Time time; SigChainLocation sigChainLocation; // Where this appeared in the user's sigchain } record PublicKeyV2Base { KID kid; boolean isSibkey; boolean isEldest; Time cTime; Time eTime; SignatureMetadata provisioning; union { null, SignatureMetadata } revocation; } record PublicKeyV2NaCl { PublicKeyV2Base base; union { null, KID } parent; DeviceID deviceID; string deviceDescription; DeviceTypeV2 deviceType; } fixed PGPFingerprint(20); record PublicKeyV2PGPSummary { PublicKeyV2Base base; PGPFingerprint fingerprint; array identities; } variant PublicKeyV2 switch (KeyType keyType) { case NACL: PublicKeyV2NaCl; case PGP : PublicKeyV2PGPSummary; default : void; } record UserPlusKeysV2 { UID uid; string username; Seqno eldestSeqno; // =0 for healty users, and 216 for deleted users StatusCode status; // Sorted by generation ascending array perUserKeys; map deviceKeys; map pgpKeys; union { null, string } stellarAccountID; map remoteTracks; union { null, ResetSummary } reset; // Unstubbed is true if no links in the User were stubbed when this // UPAK was derived. // Field introduced in 2.6 of UPAKs, so not all 2.6 stored UPAKs have this. We'll therefore // assume that stored upaks are stubbed by default. boolean unstubbed; } record UserPlusKeysV2AllIncarnations { UserPlusKeysV2 current; // Sorted by account version ascending, could be empty. array pastIncarnations; UserVersionVector uvv; map seqnoLinkIDs; // When we bump the minor version, bust the cache, and force a refresh UPK2MinorVersion minorVersion; // We can be marked stale via gregor, but it's still ok to load if we're offline // in some settings. boolean stale; } enum UPAKVersion { V1_1, V2_2 } /** * What we're storing for each user. At first it was UPAKs, as defined * in common.avdl. But going forward, we're going to use UserPlusKeysV2AllIncarnations. */ variant UPAKVersioned switch (UPAKVersion v) { case V1: UserPlusAllKeys; case V2: UserPlusKeysV2AllIncarnations; } enum UPKLiteMinorVersion { V0_0 } // only latest incarnation @lint("ignore") record UPKLiteV1 { UID uid; string username; Seqno eldestSeqno; StatusCode status; // Sorted by generation ascending map deviceKeys; union { null, ResetSummary } reset; } @lint("ignore") record UPKLiteV1AllIncarnations { UPKLiteV1 current; array pastIncarnations; map seqnoLinkIDs; UPKLiteMinorVersion minorVersion; } }