Files
buzz/deploy/charts/buzz/values.schema.json
Jordan Mecom 769ac70b74 fix(media): require authenticated reads (#4610)
This change requires a valid signed Blossom authorization request and
current relay membership for every media GET and HEAD request. It
removes the unauthenticated compatibility path and updates desktop reads
to send the required authorization.

This blocks anonymous retrieval and access after relay-membership
revocation. It does not yet bind a blob to its originating channel, so
someone removed from a private channel can still read a known blob while
remaining a relay member. That channel-ACL follow-up remains required
before closing the full finding.

## Testing

- `git diff --check origin/main...codex/security-media-read-auth`
- Rebased onto `origin/main` at `5c98932`
- Full CI pending

Originating Buzz thread:
`buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1`

---------

Signed-off-by: Jordan Mecom <jm@squareup.com>
Signed-off-by: Alex Rosenzweig <arosenzweig@squareup.com>
Signed-off-by: Eli Foster <efoster@squareup.com>
Co-authored-by: Eli Foster <efoster@squareup.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 00:46:42 +00:00

302 lines
11 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Buzz Helm chart values",
"description": "Schema for values.yaml. Catches misconfiguration at `helm install` time before _validate.tpl runtime fails. Both layers are intentional: schema rejects malformed inputs; templates reject inconsistent combinations.",
"type": "object",
"additionalProperties": true,
"properties": {
"quickstart": {
"type": "boolean",
"description": "Master toggle for evaluation profile (enables postgresql + redis subcharts and chart-side autogen). Not GitOps-safe."
},
"image": {
"type": "object",
"additionalProperties": false,
"properties": {
"repository": { "type": "string", "minLength": 1 },
"tag": { "type": "string" },
"pullPolicy": { "type": "string", "enum": ["Always", "IfNotPresent", "Never"] },
"pullSecrets": {
"type": "array",
"items": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string" } } }
}
},
"required": ["repository", "pullPolicy"]
},
"replicaCount": {
"type": "integer",
"minimum": 1,
"description": "Replica count for the relay Deployment. replicaCount > 1 requires Redis (for buzz-pubsub) — enforced by _validate.tpl. Git storage does NOT need ReadWriteMany: git state is object-store-backed and repo names live in Postgres, so ReadWriteOnce is fine per replica."
},
"relayUrl": {
"type": "string",
"pattern": "^(wss?://.+)?$",
"description": "Public wss:// URL clients connect to. Required (validated by _validate.tpl). Drives RELAY_URL, default mediaBaseUrl, default ingress host."
},
"mediaBaseUrl": {
"type": "string",
"pattern": "^(https?://.+)?$"
},
"ownerPubkey": {
"type": "string",
"pattern": "^([0-9a-f]{64})?$",
"description": "64-char lowercase hex Nostr pubkey of the relay operator. Required when relay.requireRelayMembership=true."
},
"secrets": {
"type": "object",
"additionalProperties": false,
"properties": {
"existingSecret": { "type": "string", "description": "Name of an externally managed Secret. Production / GitOps path." },
"relayPrivateKey": { "type": "string" },
"gitHookHmacSecret": { "type": "string" }
}
},
"relay": {
"type": "object",
"additionalProperties": true,
"properties": {
"bindAddr": { "type": "string", "minLength": 1 },
"maxConnections": { "type": "integer", "minimum": 1 },
"maxConcurrentHandlers": { "type": "integer", "minimum": 1 },
"sendBuffer": { "type": "integer", "minimum": 1 },
"drainJitterMs": { "type": "integer", "minimum": 0 },
"requireAuthToken": { "type": "boolean" },
"requireRelayMembership": { "type": "boolean" },
"allowNipOaAuth": { "type": "boolean" },
"huddleAudioAvailable": {
"type": ["boolean", "null"],
"description": "Whether relay huddle audio is available. null means chart default: true for one replica, false for replicaCount > 1. Explicit true with replicaCount > 1 means the operator accepts/owns external multi-pod audio/SFU behavior."
},
"pubkeyAllowlist": { "type": "boolean" },
"corsOrigins": {
"type": "array",
"items": { "type": "string" }
},
"ephemeralTtlOverride": { "type": "integer", "minimum": 0 },
"command": {
"type": "array",
"items": { "type": "string" },
"description": "Optional relay container entrypoint override. Empty preserves the image default."
},
"args": {
"type": "array",
"items": { "type": "string" },
"description": "Optional relay container arguments override. Empty preserves the image default."
},
"extraVolumeMounts": {
"type": "array",
"items": { "type": "object" },
"description": "Raw Kubernetes volumeMount fragments appended to the relay container."
}
}
},
"extraInitContainers": {
"type": "array",
"items": { "type": "object" },
"description": "Raw Kubernetes init-container fragments appended to the relay Pod."
},
"extraVolumes": {
"type": "array",
"items": { "type": "object" },
"description": "Raw Kubernetes volume fragments appended to the relay Pod."
},
"service": {
"type": "object",
"additionalProperties": true,
"properties": {
"type": { "type": "string", "enum": ["ClusterIP", "NodePort", "LoadBalancer"] },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"healthPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
"metricsPort": { "type": "integer", "minimum": 1, "maximum": 65535 }
}
},
"serviceAccount": {
"type": "object",
"additionalProperties": false,
"properties": {
"create": { "type": "boolean" },
"name": { "type": "string" },
"annotations": { "type": "object" }
}
},
"podDisruptionBudget": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"minAvailable": { "oneOf": [{ "type": "integer" }, { "type": "string" }] },
"maxUnavailable": { "oneOf": [{ "type": "integer" }, { "type": "string" }] }
}
},
"ingress": {
"type": "object",
"additionalProperties": true,
"properties": {
"enabled": { "type": "boolean" },
"className": { "type": "string" },
"annotations": { "type": "object" },
"hosts": { "type": "array" },
"tls": { "type": "array" }
}
},
"httproute": {
"type": "object",
"additionalProperties": true,
"properties": {
"enabled": { "type": "boolean" },
"parentRefs": { "type": "array" },
"hostnames": { "type": "array", "items": { "type": "string" } },
"rules": { "type": "array" }
}
},
"persistence": {
"type": "object",
"additionalProperties": false,
"properties": {
"git": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"mountPath": { "type": "string", "minLength": 1 },
"storageClass": { "type": "string" },
"accessMode": { "type": "string", "enum": ["ReadWriteOnce", "ReadWriteMany", "ReadOnlyMany", "ReadWriteOncePod"] },
"size": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)?$" },
"annotations": { "type": "object" },
"existingClaim": { "type": "string" }
}
}
}
},
"postgresql": {
"type": "object",
"additionalProperties": true,
"properties": { "enabled": { "type": "boolean" } }
},
"externalPostgresql": {
"type": "object",
"additionalProperties": false,
"properties": {
"url": { "type": "string", "pattern": "^(postgres(ql)?://.+)?$" }
}
},
"redis": {
"type": "object",
"additionalProperties": true,
"properties": { "enabled": { "type": "boolean" } }
},
"externalRedis": {
"type": "object",
"additionalProperties": false,
"properties": {
"url": { "type": "string", "pattern": "^(rediss?://.+)?$" }
}
},
"s3": {
"type": "object",
"additionalProperties": false,
"properties": {
"endpoint": { "type": "string", "pattern": "^(https?://.+)?$" },
"bucket": { "type": "string", "minLength": 1 },
"region": {
"type": "string",
"description": "Optional S3 region used for SigV4 signing. When empty, BUZZ_S3_REGION is omitted so the relay can use AWS_REGION or its own default."
},
"addressingStyle": {
"type": "string",
"enum": ["path", "virtual"],
"description": "S3 URL style shared by media and Git/CAS clients. Defaults to path for bundled MinIO compatibility."
},
"accessKey": { "type": "string" },
"secretKey": { "type": "string" }
}
},
"minio": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"image": { "type": "string", "minLength": 1 },
"mcImage": { "type": "string", "minLength": 1 },
"persistence": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"size": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)?$" }
}
}
}
},
"git": {
"type": "object",
"additionalProperties": false,
"properties": {
"maxPackBytes": { "type": "integer", "minimum": 1 },
"packCachePath": { "type": "string", "minLength": 1 },
"packCacheMaxBytes": { "type": "integer", "minimum": 0 },
"packCacheMaxConcurrentPopulations": { "type": "integer", "minimum": 1 },
"packCacheVolumeSize": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)?$" },
"maxReposPerPubkey": { "type": "integer", "minimum": 1 },
"maxConcurrentOps": { "type": "integer", "minimum": 1 }
}
},
"migrate": {
"type": "object",
"additionalProperties": false,
"properties": {
"autoMigrate": { "type": "boolean" },
"preUpgradeJob": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"resources": { "type": "object" },
"backoffLimit": { "type": "integer", "minimum": 0 },
"activeDeadlineSeconds": { "type": "integer", "minimum": 1 }
}
}
}
},
"serviceMonitor": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"namespace": { "type": "string" },
"interval": { "type": "string" },
"scrapeTimeout": { "type": "string" },
"labels": { "type": "object" }
}
},
"pairingRelay": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"url": {
"type": "string",
"pattern": "^(wss?://.+)?$",
"description": "Public WebSocket URL advertised to clients for NIP-AB device pairing."
},
"replicaCount": { "type": "integer", "minimum": 1 },
"service": {
"type": "object",
"additionalProperties": false,
"properties": {
"type": { "type": "string", "enum": ["ClusterIP", "NodePort", "LoadBalancer"] },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"annotations": { "type": "object" }
}
},
"podAnnotations": { "type": "object" },
"podLabels": { "type": "object" },
"resources": { "type": "object" }
}
},
"extraManifests": {
"type": "array"
}
}
}