feat: add bounded private acquisition transport
This commit is contained in:
parent
805691a71b
commit
845da21a9f
3 changed files with 56 additions and 0 deletions
|
|
@ -32,5 +32,10 @@ python -m unittest discover -s tests -v
|
|||
python scripts/check_public_repo.py .
|
||||
```
|
||||
|
||||
`scripts/materialize_private_drive_files.ps1` is the bounded transport used by
|
||||
the acquisition workflow. It accepts authenticated download references over
|
||||
standard input, rejects path traversal, and verifies byte sizes before files
|
||||
enter PrivateStash. It never prints download credentials.
|
||||
|
||||
No project license has been selected yet. Until that decision is recorded,
|
||||
the contents are not offered under an open-source license.
|
||||
|
|
|
|||
|
|
@ -31,3 +31,7 @@ project artifact is created, edited, renamed, or reorganized there.
|
|||
4. Create a sanitized derivative in the public repository.
|
||||
5. Run automated guards and manually review the staged diff.
|
||||
6. Commit and push the private evidence before the public claim that cites it.
|
||||
|
||||
During Drive acquisition, authenticated download references are ephemeral and
|
||||
must be passed to the bounded materializer over standard input. They must not be
|
||||
written to scripts, manifests, command history, or Git.
|
||||
|
|
|
|||
47
scripts/materialize_private_drive_files.ps1
Normal file
47
scripts/materialize_private_drive_files.ps1
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Root
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$rootPath = (Resolve-Path -LiteralPath $Root).Path
|
||||
$rootPrefix = $rootPath.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
|
||||
|
||||
while (($line = [Console]::In.ReadLine()) -ne $null) {
|
||||
if ($line -eq '__END__') {
|
||||
break
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($line)) {
|
||||
continue
|
||||
}
|
||||
|
||||
$item = $line | ConvertFrom-Json
|
||||
if (-not $item.relative_path -or -not $item.download_url) {
|
||||
throw 'Each input line must contain relative_path and download_url.'
|
||||
}
|
||||
|
||||
$relativePath = $item.relative_path.Replace('/', [IO.Path]::DirectorySeparatorChar)
|
||||
$destination = [IO.Path]::GetFullPath((Join-Path $rootPath $relativePath))
|
||||
if (-not $destination.StartsWith($rootPrefix, [StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "Refusing path outside acquisition root: $($item.relative_path)"
|
||||
}
|
||||
|
||||
$parent = Split-Path -Parent $destination
|
||||
New-Item -ItemType Directory -Path $parent -Force | Out-Null
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $item.download_url -OutFile $destination
|
||||
|
||||
$actualSize = (Get-Item -LiteralPath $destination).Length
|
||||
if ($null -ne $item.expected_size -and $actualSize -ne [long]$item.expected_size) {
|
||||
throw "Size mismatch for $($item.relative_path): expected $($item.expected_size), got $actualSize"
|
||||
}
|
||||
|
||||
if ($item.expected_sha256) {
|
||||
$actualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $destination).Hash.ToLowerInvariant()
|
||||
if ($actualHash -ne $item.expected_sha256.ToLowerInvariant()) {
|
||||
throw "SHA-256 mismatch for $($item.relative_path)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output ("OK`t{0}`t{1}" -f $actualSize, $item.relative_path)
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue