On 9/01/2014 11:44 AM, Toby Elliott wrote:
> 2) The account identifier (we call it the uid) is simply a mapping from the
> username to an externally-chosen integer, and isn't derived as a function.
> That enables services to index users by an integer rather than a string, and
> it may be a constant across multiple services. Changing that will cause the
> user to start a completely new sync account, leaving us with all their old
> data sitting there.
>
> Tokens expire after a specifically configured period, which addresses the
> second bullet point (and the third, to an extent) in terms . Perhaps an HMAC
> error should trigger a fresh round of auth before proceeding to worry about
> other possibilities?
>
> If a client does a complete account reset, it would probably be best if they
> kicked off their new interactions with the Sync server by deleting everything.
I'm not thrilled about making the tokenserver responsible for sync-key
management. It'd work, sure, but it seems like a layering violation.
Restating an implicit intermediate goal: resetting your account should
blow away your sync data, causing all clients to update their encryption
keys and re-sync from scratch.
Is that accurate or have I lost some nuance?
Would the following work without having to special-case things in the
tokenserver?
When a client switches to using a new encryption key
(e.g. after successful password reset):
* re-auth with the tokenserver, to update the
generation number
* delete all data on the sync node (we have an atomic API
operation for this already)
* re-sync from scratch
When a client encounters an HMAC error:
* re-auth with the tokenserver, which may in turn
force re-auth with FxA due to generation change
* if the encryption key was changed, try syncing again
and it will probably work this time
* if the encryption key was not changed, someone has
left junk on the sync node; delete all data
and try syncing again
By always doing a tokenserver re-auth before deleting data from the
node, this should prevent clients getting into a slap-fight over which
encryption key is currently active. They're gated by the generation
number stored in the tokenserver.
The junk-cleaning-up behaviour in the HMAC-error case would heal from
situations like a client crashing after it changes the password, but
before it has a chance to delete things form the storage node.
Sticking point: clients that write old-key-encrypted data into the store
*after* it has been cleared. Consistent use of X-If-Unmodified-Since
could avoid this, but I don't think we use it consistently.
So the downside here would be more client code churn. The
tokenserver-based approach is probably simpler to implement before our
impending deadline, and almost certainly simpler to implement *reliably*.
Cheers,
Ryan
> On Jan 8, 2014, at 3:36 PM, Brian Warner <[email protected]> wrote:
>
>>
>> ["To:" folks, please review]
>>
>> ckarlof, nalexander, and myself had a meeting today to figure out what
>> should happen in Sync+FxAland when you change or reset your FxA account
>> password. We specifically cared about:
>>
>> * resetting your account (new password, new encryption key) should *not*
>> result in clients seeing HMAC errors, when they try to decrypt new
>> records with the old key or vice-versa
>>
>> * changing the password (new password, unchanged encryption key) should
>> sooner-or-later cause all other clients to lose access, and their
>> users should be prompted to re-login
>>
>> * resetting the account (new password, new encryption key) should also
>> cause other clients to lose access and be prompted to re-login
>>
>>
>> To support this, we're proposing the following changes:
>>
>> * the fxa-auth-server will remember a "generation number" for each
>> account. Each account-reset and change-password event increments the
>> generation number. The generation will be included in signed
>> certificates returned by the /certificate/sign API.
>>
>> * when the client submits a signed assertion to the tokenserver's
>> "please give me a token" API, it will include the hash of the
>> encryption key it is currently using (derived from kB). nalexander:
>> I'd recommend this value be a sibling of the key you're already
>> deriving from kB, either by using a different ctxInfo string, or by
>> extracting an extra 32 bytes from the existing HKDF operation. Neither
>> is derivable from the other.
>>
>> * the Sync tokenserver will maintain a table with three columns:
>> - FxA Account Identifier
>> - FxA generation number
>> - Sync account identifier (endpoint? collection-id? I don't know the
>> right lingo)
>>
>> * The Sync account identifier must be a consistent function of (FxA
>> account-id, hash-of-encryption-key). Previously it was merely a
>> consistent function of the FxA account-id.
>>
>> * If the tokenserver gets a please-give-me-a-token request with a
>> generation number that's lower than the one currently stored, it
>> should reject the request. If it gets a cert with a higher generation
>> number, it should update the table.
>>
>> * the FxA/Sync client code should respond to most errors (specifically
>> token-expired and old-generation errors) by asking the user to
>> re-login
>>
>>
>> The idea is:
>>
>> * when client#1 changes the FxA account password, they get the same kB
>> but a new generation number. As soon as their Sync client code talks
>> to the tokenserver, all other clients will be locked out (the
>> tokenserver will no longer accept their older-generation
>> certificates), and will be prompted to re-login (with the new
>> password). The window of revocation will be as short as the token
>> expiration time. If client#1 crashes and never manages to talk to the
>> Sync server, other clients will continue to work until their tokens
>> and certificates expire.
>>
>> * if client#1 resets the account (forgot-password), they get a new kB
>> and a new generation number. When they sync, they'll get a new Sync
>> account-id and a new place for server-side data, independent of the
>> old place. Client#2 (who is still using the old key) will keep using
>> the old place. No matter how long the clients keep using their old
>> keys, they won't interfere with each other's ciphertext, and no client
>> will observe a wrong-key-provoked HMAC failure. Eventually all certs
>> and tokens will expire, and they'll stop using the old place.
>>
>> * the tokenserver can run a query to find stale Sync-account-identifiers
>> (lowest generation number for the same FxA account identifier) to mark
>> for garbage-collection. We might want to store a last-used timestamp
>> here too, to defer GC for a day or two after the last client stops
>> touching it.
>>
>> The overall goal is to avoid requiring a back-channel between the FxA
>> auth-server and the Sync tokenserver. The generation numbers should be
>> useful for other RPs that want slightly faster revocation properties
>> too.
>>
>>
>> thoughts?
>> -Brian
>
_______________________________________________
Sync-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/sync-dev