Skip to content

A minimalist anonymous reservation system

Notifications You must be signed in to change notification settings

tiliv/reservations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reservations

A lightweight Google Calendar proxy for free/busy public calendars.

Please Stand By.

Parts

ACCOUNTS:

  • GitHub (1), staff, reveals scheduling history activity

SECRETS:

  • "Scheduler secret": An official GitHub API token limited to our project
    • Rotated: we invalidate brute force or latent discovery by auto rotating them
  • "Wrapped secret": The secret, with wrappers per member
    • Rotated: changes as of as the secret is rotated. builds new wrappers
    • Public: brute force risks are created here. because of rotation, broken wrappers can't create disclosures.
  • "Passwords": Member passphrases
    • Private: we know only the intermediate memory-hard evidence of your passphrase
    • Stable: member can change it or have us set it out of band
  • Member appointment nonces

EVIDENCE:

  • A nonce manifest for all booked upcoming appointments
    • Maintained: can be made to backport removals from the calendar
    • Managed: can be set explicitly by staff to create appointments with public codes
      • This might help us with group reservation, like attending a class

Scheduled

Variables:

  1. ROTATE_TIME
  2. MARGIN_TIME (constant < ROTATE_TIME)
  3. CACHE_TIME (ROTATE_TIME + MARGIN_TIME)

Rotate the public-exposed evidence of key use, which is brute forcible only for expired intermediates:

  • (todo: workflow) rotates the GitHub API token as a secret
  • $ bin/make-key.sh makes a new secrets/data_key.b64
  • $ bin/encrypt-artifact.sh remakes wrappers from the longer-lived hash intermediates of member passphrases
  • .github/workflows/request-reservation.yml deploys the currently wrapped secret

We rotate the private key too because no matter what it is, only the member's passphrase opens that wrapper.

Without a persistent key to attack, the brute force risks are fully mitigated at every expiry. The window can be controlled by coordinating Cloudflare Edge cache expiry to be longer by a margin than the key rotation. The margin is how long users have before the GitHub API token key is no longer valid.

For not longer than the margin, the previously distributed key and the new key are both valid. When the prior key is removed, the margin should be over and its distribution is definitively expired if encountered in web caches.

If attacked, the wrappers can only reveal the intermediate keys. Deriving these keys is memory-hard, and their complexity limits the viability of free-form key input guesses.

For: new users

Adding a user:

  • $ bin/add-pass.sh makes a wrapper for that member to decrypt
  • Commit changed artifacts (new wrapper)
  • Build and publish static site so that the wrapper is public

For: existing users

Changing their passphrase:

  • (todo: workflow) to update passphrase intermediate
  • (todo: bin) to drop wrappers
  • $ bin/encrypt-artifact.sh using the intermediate keys and current secrets/data_secret.b64
  • Commit changed artifacts (lost wrapper, new wrapper)
  • Build and publish static site so that the wrapper is public

Requesting a reservation:

  • $ bin/request-reservation.sh (with iCal-like input requirements) to email the calendar booking to the target layer
  • Commit changed artifacts (the appointment nonce in a protected log)

When a client triggers the request, they provide an automated nonce only their device knows. This is the receipt of their request and it exists only on their device. They can paste this somewhere for verification, but can be invisible when things are in normal working order. It can be recovered via member contact because it is recorded on the protected calendar information when it was supplied to us. It is not cryptographically relevant, only a UID.

After a reservation has been sent, a staff member must approve it in Google Calendar by normal means. The work to this point only brings us to the point of proposing an appointment from known members, on a public site, without a backend for oauth APIs.

Editing/Cancelling a reservation:

  • (todo: workflow) uses a known member's locally-recorded nonce to propose new details about an appointment by indirection

As a theme, write access to the calendar is unavailable except via staff empowered by normal methods.

The repository can keep all currently open appointment nonces (backporting any pruning from the original calendar by inclusion) in a protected area. The list of nonces empowers valid requests to the workflow to propose new appointment details, but it is centralized only here, where appointment evidence should be made tangible, but anonymous. It is a low-fidelity rendering of the calendar from the present week forward.

About

A minimalist anonymous reservation system

Resources

Stars

Watchers

Forks