git@cosmocr.at/gitweb.git @ main · summary refs log
main / scripts / update-access.sh /
scripts/update-access.sh · 3.6 KiB · raw
view: SourceMarkdown ☑ force

#!/bin/bash

update-access.sh — edit the Access file of an upspin directory (typically a

gitweb-hosted repo) and re-share, so the new grants actually take effect on

already-uploaded files.

Usage:

scripts/update-access.sh [flags]

directory whose Access file to update,

e.g. rpg137@gmail.com/myrepo.git

--file FILE replace the Access file with FILE (non-interactive);

default is to open the current one in $EDITOR

--fix-only leave the Access file alone, only re-share (use after an

Access change made by other means)

--force rewrap keys regardless of current state; needed for the

change to stick after REMOVING readers

--config FILE upspin config to use (default $HOME/upspin/config)

Why the re-share step: with ee packing, each file's decryption key is

wrapped per reader at write time. Editing Access changes who should read,

but not the wrapped keys — upspin share -fix -r reconciles them (adding

the cleartext "all" entry for read:all, and per-user wraps for new grants).

Revocation caveat: removing a reader (even with --force) only removes their

wrapped key going forward; they may have already saved file keys or content.

For real secrecy after a leak, rotate keys / re-encrypt (see upspin rotate

and upspin share -help).

set -euo pipefail

die() { echo "update-access.sh: $*" >&2; exit 1; }

CONFIG="${HOME}/upspin/config" FILE="" FIXONLY=0 FORCE=0 ARGS=() while [ $# -gt 0 ]; do case "$1" in --file) shift; FILE="${1:?--file needs a file}" ;; --fix-only) FIXONLY=1 ;; --force) FORCE=1 ;; --config) shift; CONFIG="${1:?--config needs a file}" ;; -h|--help) sed -n '2,29p' "$0" | sed 's/^# {0,1}//'; exit 0 ;; -*) die "unknown flag $1" ;; *) ARGS+=("$1") ;; esac shift done [ "${#ARGS[@]}" -eq 1 ] || die "usage: update-access.sh [--file FILE | --fix-only] [--force] [--config FILE] " DIR="${ARGS[0]%/}" [ -z "$FILE" ] || [ "$FIXONLY" = 0 ] || die "--file and --fix-only are mutually exclusive"

command -v upspin >/dev/null || die "upspin not found" [ -f "$CONFIG" ] || die "upspin config not found: $CONFIG" case "${DIR%%/}" in @.) ;; *) die "path must start with an upspin user (user@domain/...): $DIR" ;; esac UP() { upspin -config="$CONFIG" "$@"; }

UP ls "$DIR" >/dev/null 2>&1 || die "$DIR does not exist or is not readable" ACCESSPATH="$DIR/Access"

if [ "$FIXONLY" = 0 ]; then TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT NEW="$TMP/Access" if [ -n "$FILE" ]; then cp "$FILE" "$NEW" else # Start from the current Access file (empty if none exists yet — note # that without one, access is governed by the nearest ancestor's). UP get "$ACCESSPATH" > "$NEW" 2>/dev/null || : > "$NEW" [ -t 0 ] || die "stdin is not a terminal; use --file for non-interactive updates" OLDSUM=$(sha256sum "$NEW" | cut -d' ' -f1) ${EDITOR:-vi} "$NEW" if [ "$(sha256sum "$NEW" | cut -d' ' -f1)" = "$OLDSUM" ]; then echo "Access unchanged; re-sharing anyway" fi fi [ -s "$NEW" ] || die "refusing to install an empty Access file (rm $ACCESSPATH to fall back to inherited access)" UP cp "$NEW" "$ACCESSPATH" echo "==> installed $ACCESSPATH:" sed 's/^/ /' "$NEW" fi

echo "==> re-sharing (rewrapping file keys to match Access)" if [ "$FORCE" = 1 ]; then UP share -fix -force -r -q "$DIR" else UP share -fix -r -q "$DIR" fi

Show the resulting state; any "keys disagree" section here means trouble.

echo "==> resulting access:" UP share -d "$DIR" | sed 's/^/ /' | head -20