AnVIL + Terra meets git-drs
Version-controlled dataset layouts—without copying controlled-access payloads into Git.
Reference proof of concept · July 2026
Git moves references. AnVIL moves bytes.
| User A |
Git |
User B |
AnVIL |
| Add references with ADC-authorized metadata validation |
Commit canonical DRS URI, size, and checksum |
Clone and authenticate with an independent Google identity |
Hydrate from a fresh authorized URL and verify bytes |
0 payload bytes
committed to Git
2 identities
authenticate independently
1 reference
stays canonical and portable
Security boundary: Git visibility reveals paths and DRS identifiers; it never grants authorization to the underlying data.
One reference model, four perspectives
Data reference author
Publish a reviewable, versioned dataset layout—one object or a manifest—without downloading payloads.
Data consumer
Clone pointers, authenticate independently, then hydrate everything or only paths matching a pattern.
Unauthorized reader
Inspect repository history but receive a clear denial when attempting controlled-data hydration.
Repository maintainer
Review deterministic pointers, diagnose provider failures, and run clean-clone acceptance tests.
Out of scope: uploads, record mutation, provider copying, remote GC, and workspace-table sync.
Add once. Publish with ordinary Git.
```bash
gcloud auth application-default login
git drs add-ref --remote anvil \
drs://authority/object-1 data/sample.cram
# Validate a batch before writing
git drs add-ref --remote anvil \
--manifest references.tsv --dry-run
git add .git-drs/ .gitattributes data/
git commit -m "Add AnVIL data references"
git push
```
### Published
- Canonical DRS URI pointers
- Paths and Git history
- `.gitattributes`
- Allowlisted, non-secret remote configuration
### Never published
- Payload bytes or cache content
- Tokens, headers, or ADC files
- Signed download URLs
A clean clone is enough
```bash
gcloud auth application-default login
git clone
cd
# Hydrate every authorized reference
git drs pull
# Or only one dataset slice
git drs pull -I "data/*.cram"
```
> No author cache, local Git config, token, or signed URL is transferred.
</div>
| Stage | Action |
|---|---|
| **Git** | Clone pointer and safe public config |
| **User B** | Supply ADC; choose all or include pattern |
| **Resolver** | Fetch current metadata and fresh access |
| **Cache** | Download, verify, atomically promote |
| **Worktree** | Hydrate only after validation |
</div>
---
## AnVIL manifest to pointer-only GitHub repo
### 1. Configure and add references
```bash
git init
git drs remote add terra anvil \
--drs-endpoint https://data.terra.bio \
--auth google-adc --mode read-only
# Download the TSV from AnVIL Data Explorer first.
manifest=/tmp/anvil-manifest-38dc7537.tsv
scripts/anvil-add-ref-commands.sh "$manifest" \
> /tmp/add-anvil-refs.sh
cat /tmp/add-anvil-refs.sh
bash /tmp/add-anvil-refs.sh
```
### 2. Commit, hydrate, and publish
```bash
git add .git-drs/ .gitattributes '*.tsv'
git commit -m "Add references to AnVIL data"
# Materialize only TSVs locally.
git drs pull -I "*.tsv"
git status
git branch -M main
git remote add origin \
https://github.com/bwalsh/\
ANVIL_1000G_PRIMED_data_model.git
git push -u origin main
```
> **Result:** the worktree contains hydrated TSV data; GitHub contains only DRS pointers and safe public configuration.
---
## Portable pointer + safe configuration
### Tracked pointer
```text
version https://calypr.github.io/spec/v1
oid drs://authority/object-1
size 987654321
sha256 8d969eef…
```
The DRS URI stays canonical. A checksum describes content; it does not identify the AnVIL record.
### Tracked `.git-drs/config.yaml`
```yaml
version: 1
default_remote: anvil
remotes:
anvil:
type: terra
endpoint: https://data.terra.bio
auth: google-adc
mode: read-only
```
Only allowlisted public settings load. Secret-like or unknown sensitive fields fail closed.
---
## Provider-neutral resolution breaks Syfon coupling
```text
Commands Resolver interface Identities
add-ref · pull · ping -> GetObject · GetAccess -> remote · cache · content
|
+----------+----------+
| |
AnVILResolver SyfonResolver
Google ADC · routing Gen3 · local behavior
```
### Design rules
- Commands depend on one resolver contract.
- The configured remote selects the resolver.
- Authentication and provider routing stay behind the interface.
- There is no user-facing `--remote-type` switch.
---
## Three identities—not one overloaded OID
REMOTECanonical DRS URI
Normalized provider record identity. Committed to Git and used for object and access resolution.
LOCALCache OID
Filesystem-safe SHA256 of a versioned prefix plus normalized DRS URI. Never replaces remote identity.
CONTENTContent SHA256
Durable integrity metadata, when supplied. Used to verify bytes—not to locate the record.
```text
cache_oid = sha256("git-drs-anvil-ref:v1\n" + normalized_drs_uri)
```
> **Download invariant:** fresh access → temporary file → verify size/checksum → atomic cache promotion → hydrate worktree.
---
## Good component coverage; one decisive gap
IMPLEMENTEDFocused coverage
- Resolver contract and errors
- Terra remote and safe config
- Canonical pointer/cache key
- Terra ping and push refusal
PARTIALWorkflow coverage
- Manifest validation and dry run
- Pull size/SHA256 checks
- Selective hydration
- Cache reuse behavior
MISSINGPOC acceptance
- Independent User A/User B state
- Real or contract-faithful AnVIL
- Expired URL and retry journey
- Authorization leak audit
| Arrange | Act | Assert |
|---|---|---|
| Separate homes, config, ADC, caches | Commit → clone → authenticate → pull | Verified bytes; isolated credentials |
---
## Most original blockers are now closed
### Implemented
- ADC-backed `AnVILResolver` handles metadata and access.
- Terra `add-ref` and pull use provider-neutral resolution.
- Remote config selects behavior; `--remote-type` is deprecated.
- Terra pointers retain DRS URI, size, and optional SHA256.
- Cache keys are separate from content checksums.
### Still incomplete
- Compact AnVIL IDs still require the trusted Terra resolver.
- Service-info does not discover auth, provider, or capabilities.
- Remote setup retains provider-specific command shapes.
- Downloads lack bounded concurrency, retry, cancellation, and expired-URL re-resolution.
- Production and independent two-user acceptance remain unverified.
> **Bottom line:** an implemented vertical slice still needs production-contract validation, resilience, and end-to-end proof.
---
## Turn the vertical slice into a proven POC
P0 · VERIFYProve production fit
- Confirm endpoint and OAuth scopes
- Certify object/access contracts
- Test slash and compact DRS IDs
- Run clean two-user clone/pull
- Audit logs and history
P1 · HARDENMake it resilient
- Trusted authority routing
- Persist auth discovery
- Expired-URL re-resolution
- Bounded retry and concurrency
- Remote diagnostics and CI
P2 · GENERALIZEKeep DRS composable
- Unify `remote add`
- Resolver/auth interfaces
- CGC and Synapse fixtures
- Keep publishing provider-specific
- Defer mutation and copying
---
## Decisions needed to start the POC
1. Which authoritative AnVIL resolver contract, endpoint, and OAuth scopes will we certify?
2. What stable test objects cover checksummed, non-checksummed, large, and denied cases?
3. Is the pointer extension compatible with every parser that must read it?
4. What is the supported override policy for tracked versus local remote configuration?
5. Who owns the independent-user acceptance environment and compatibility matrix?
### Questions?
The maintained design source is [`docs/anvil-terra-poc.md`](/git-drs/anvil-terra-poc.html).