function validateAndNormalizePermissions (permissions) {
  if (typeof permissions !== 'object') throw new Error(`Permissions must be an object`)
  for (let key in permissions) {
    if (key === 'publicFiles' || key === 'privateFiles') {
      if (!Array.isArray(permissions[key])) throw new Error(`Permission '${key}' should be an array`)
      for (let v of permissions[key]) {
        if (!v.path || typeof v.path !== 'string') throw new Error(`'${key}' permissions must have a .path string`)
        Object.assign(v, parseSimplePathSpec(v.path))
        delete v.path

        v.access = v.access || 'read'
        if (!VALID_ACCESS.includes(v.access)) throw new Error(`'${key}' permissions .access must be one of: ${VALID_ACCESS.join(', ')}`)

        if (!v.prefix.startsWith('/')) v.prefix = `/${v.prefix}`
        while (v.prefix.endsWith('/')) v.prefix = v.prefix.slice(0, -1)
        if (!v.prefix || v.prefix === '/') throw new Error(`'${key}' permissions .path can not be '/'`)
        if (!v.extension) throw new Error(`'${key}' permissions .path must include an extension`)
      }
    } else {
      throw new Error(`Invalid permission key: ${key}`)
    }
  }
}
@typedef {Object} EnumeratedSessionPerm
@prop {String} prefix
@prop {String} extension
@prop {String} location
@prop {String} recordType
@prop {String} access