geenforce: HTTPS payload delivery (content-addressed blob store + endpoint)

Lets share-less (Intune/local-account) PCs pull installers the manifest
references over HTTPS instead of SMB - the general capability the whole fleet
migrates toward. New ManifestBlob registry (migration 0002) with bytes on disk
at instance/geenforce/payloads/<sha256> (deduped by content); service.store_blob
+ blob_path; client-facing GET /api/geenforce/payload/<sha256> (geenforce.fetch
token, ETag=hash, serves the blob store or an inline DB payload by hash). The
serializer now emits PayloadSource/PayloadSha256/PayloadRef for http/inline
entries only (smb entries round-trip unchanged - parity green). CLI
'flask geenforce add-payload <file>' registers a blob and prints its sha256.
This is the shopdb half (B1); the PS client/engine fetch is B2.
This commit is contained in:
cproudlock
2026-07-21 10:10:59 -04:00
parent 60e2947fc7
commit b00ef72581
8 changed files with 268 additions and 6 deletions

View File

@@ -351,3 +351,21 @@ class PcTypeAlias(db.Model):
__table_args__ = (
db.UniqueConstraint('aliasgroup', 'aliasname', name='uq_alias_group_name'),
)
class ManifestBlob(db.Model):
"""Content-addressed payload blob for http-delivered installers.
Bytes live on disk at <instance>/geenforce/payloads/<sha256> (deduped by
content, so a payload shared by many entries is stored once). Manifest
entries reference a blob by payloadsha256; the client fetches it from
GET /api/geenforce/payload/<sha256> over HTTPS and verifies the hash. This
is how big installers reach share-less (Intune/local-account) PCs.
"""
__tablename__ = 'manifestblobs'
sha256 = db.Column(db.String(64), primary_key=True)
filename = db.Column(db.String(255), nullable=False)
contenttype = db.Column(db.String(128), nullable=True)
sizebytes = db.Column(db.BigInteger, nullable=False)
createdat = db.Column(db.DateTime, nullable=False)