Bring in contractors. Keep the core.
A contractor at Acme Security, from day 1 to their last day, working on one part of a Go monorepo.
Arrow keys or space to move. F to present.
acme-security/platformon GitHubalice's clonealice's agent
Example: Acme Security's monorepo seen three ways. The Acme team sees everything on GitHub. A contractor's clone has no scanner/, detections/ or infra/ folders, not even in the history, and pipeline/ as types only. Their AI agent gets the same or less: here pipeline/ is closed to AI agents.
Next: what goes wrong when a contractor clones today
Today, one clone hands over everything.
Every folder and every commit, including scanner/ and detections/. Their AI agent reads it all in minutes.
$ git clone [email protected]:acme-security/platform.gitReceiving objects: 100% (412,906/412,906), 1.9 GiB$ cd platform && lsapi detections docs infrapipeline scanner web$ git log --oneline | wc -l48211# every commit since day one
Their AI agentreading
- scanner/engine/probe.go
- scanner/engine/ratelimit.go
- detections/rules/http_titles.yaml
- detections/fingerprints/tls.go
- pipeline/enrich/enrich.go
- infra/prod/main.tf
- api/v2/hosts.go
Next: how your team keeps working exactly as today
Your team
Your team changes nothing.
Your engineers stay on github.com. Gitfence only serves the people you restrict.
Next: setting it up: one app, then a rule per folder
Setup
Install the app. Pick the folders.
Install the GitHub app and choose the repository, then a level per folder. Secrets are hidden by default.
platformacme-security/platformscanner/The internet scanning engineNo accessdetections/Proprietary fingerprint rulesNo accesspipeline/Ingest and enrichmentTypes onlyapi/Public APICan editweb/Customer dashboardCan editdocs/Product docsCan read.env, *.keySecrets and keys, anywhereby defaultNo access
Next: contractors coming in through your own identity provider
Contractors come from your identity provider.
Single sign-on and SCIM: when someone loses access in your IdP, they lose it here too.
Your identity provider
- Okta
- Google Workspace
- Microsoft Entra ID
SAML 2.0 or OpenID Connect, plus SCIM
- alice added to Contractorsfrom your IdP
- alice signs in with Oktasingle sign-on
- Gets the Contractors rulesweb/, api/, …
- alice deactivated in Oktaremoved from Gitfence
Next: inviting the contractor, with an NDA first if you want
Hiring
Invite them. An NDA first, if you like.
Invite by GitHub username or email. With an agreement required, no code is served until they sign.
Optional
acme-security/platformA GitHub userEmail addresses
Sign first: Contractor NDA, version 3
Create invitationI have read Contractor NDA, version 3 and I agree to it.
SignWe record your typed name, the time and the exact version you read.
Signature certificate
- Signed by
- Alice Moreau
- Signed at
- 2026-11-02 09:14 UTC
- Document SHA-256
- 9f2c41d7…e41a
Next: how their access grows over time, or ends
Decide how access grows, or ends.
A ladder you approve step by step, or a fixed end date with reminders.
- Week 1
web/andapi/Applied - Day 30Read
pipeline/Approve - Day 90Edit
pipeline/Waiting
Each step waits for you: Approve, Not yet or Skip.
Access ends 31 January 2027
- Reminder 7 days before
- Reminder 1 day before
Extend 30 daysEnd now
Next: day 1: what actually lands on their laptop
Day 1
Day 1: their clone has only their part.
scanner/ and detections/ aren't in any commit. Even the history has no trace of them.
$ git clone https://gitfence.dev/acme-security/platform.gitCloning into 'platform'...$ cd platform && lsAGENTS.md api docs go.mod pipeline web$ ls scannerls: cannot access 'scanner': No such file or directory$ git log --all --oneline -- scanner detections | wc -l0# not in any commit, not in the history
Next: how their Go code still compiles without your code
Your Go APIs, without the code behind them.
Types only keeps every exported type and signature, so their code compiles. Every body is a panic.
pipeline/enrich/enrich.goon GitHubfunc Enrich(r Result, db *GeoDB) (*Record, error) { asn, err := db.LookupASN(r.IP) if err != nil { return nil, fmt.Errorf("asn: %w", err) } return &Record{IP: r.IP, ASN: asn}, nil }
pipeline/enrich/enrich.goTypes only// Generated by Gitfence from fenced source: // types only, implementation hidden. Do not edit. func Enrich(r Result, db *GeoDB) (*Record, error) { panic("gitfence: implementation hidden") }
$ go build ./api/...# api/ compiles against the stubs
Next: their AI agent gets the same fence, or a tighter one
Their AI agent
Their AI agent stays inside the fence.
Its person's access or less. AGENTS.md explains the rules, fenced pushes are refused, and its commits are tagged.
| Folder | alice | alice's agent |
|---|---|---|
api/ | Can edit | Can edit |
pipeline/ | Types only | No accessNo AI agents |
scanner/ | No access | No access |
AGENTS.mdin every clone## Gitfence: what this copy contains Some paths are fenced. Do not create, recreate or stub fenced code. Use what your view provides, or ask for access.
$ git push origin HEAD:alice/exportremote: GITFENCE REJECTED: push toremote: alice/exportremote: x scanner/engine/ratelimit.goremote: scanner/ is fenced (hidden)remote: for this agent's scoperemote: Do instead: do not create,remote: recreate or stub fenced code ! [remote rejected] (pre-receive hook declined)# accepted commits carry a trailer:Gitfence-Agent: claude-code (of @alice-moreau)
Next: how their work comes back to your GitHub
Working together
Work arrives as normal pull requests.
Opened on github.com for the contractor. Your CI runs as usual, and Gitfence flags what needs a human.
acme-security/platformgithub.comAdd CSV export to the hosts table #418
github.com/gocarina/gocsv- Gitfence Came through the fencePassed
- Gitfence review Needs a humanWaiting for an approval
- ci / test go 1.23Passed in 3m 12s
- ci / lintPassed in 41s
Why a human: it adds a dependency. The check passes when someone other than the author approves this exact version.
Next: reviewing their pull request together, in both directions
Review together, in both directions.
Your comments reach them, minus fenced files. In Files changed, they see a diff built from their own copy and can review your team's pull requests too. Their replies land in the same GitHub thread.
On GitHub your team
#418github.comweb/hosts/export.tsxStream the rows, the way scanner/engine/probe.go does.
scanner/engine/probe.gonot sentSame change needed here later.
alice-moreau (via Gitfence): Done, it streams now.
In Gitfence alice
#418alice's viewweb/hosts/export.tsxStream the rows, the way [fenced file] does.
Done, it streams now.
Her agent can read and reply too, through Gitfence's MCP server.
Next: what happens when they need more access mid-task
Need more access? They ask, you decide.
A request with a reason. You see exactly what it would reveal before you approve.
request_access({ path: "pipeline/geo/", access: "read", reason: "Export times out in GeoDB.City" })
Can readpipeline/geo/“Export times out in GeoDB.City”
Approving shows alice-moreau the full code of 14 files in pipeline/geo/ that they can't read today.
What they clone can't be un-cloned.
Approve read accessDeny
Or give less:For 1 day insteadOne file only…
Next: how we protect your code on our side
Security
Your code, encrypted with a key we don't keep.
Readable only in memory while your people use Gitfence, then locked again.
The key exists only locked inside
- Your people's sign-ins
- Your agents' tokens
- Your recovery key, kept by you
Our database stores only locked copies of it.
acme-security/encrypted at rest
LockedUnlocked in memory
- 09:00 alice clones: unlocked in memory
- 09:40 nobody active for ten minutes
- 09:50 locked again
- Our backups contain no code.
- Not zero-knowledge: for that, self-host.
Next: where it runs, and what the audit log records
Hosted in the EU, or self-hosted.
Either way, every clone, fetch, push and agent call goes into an audit log for your SIEM.
- A server in Germany, run by an EU company
- Behind Cloudflare
- Code encrypted at rest, not in backups
- In your own infrastructure, with GitHub or GitHub Enterprise Server
- A compiled build, installed with docker compose
- Offline license, no telemetry
- Your own keys, in HashiCorp Vault
- 09:14alice-moreauclone platform
- 09:31alice's agentfetch
- 10:02alice's agentMCP check_paths
- 10:05alice-moreaupush alice/export, PR #418
- 10:07alice's agentpush rejected: scanner/
Signed webhooks to your SIEM, or export as CSV or JSON lines.
Next: their last day, and the signed record you keep
Last day
Last day: one click ends everything.
Every token and agent stops. Their pull requests stay. You keep a signed record.
- Removed from acme-security/platform
- 3 tokens revoked, including 2 AI agents
- 1 pending request closed
- Her open pull requests stay on GitHub
$ git pullfatal: remote error: Your access to acme-security/platform was removed. Ask an admin of the repository if you still need it.
Signed exit pack
- What she and her agents received, and when
- Every access change, and who approved it
- The agreements she signed
Next: how to start: a 30-day pilot on your repo
Pilot
Start with a 30-day pilot on your repo.
Your repository, your contractors, your real code. Here is what we need from you.
- A GitHub org admin to install the app
- Which folders to fence
- Your contractors' GitHub usernames
- Your identity provider, if you want SSO
Try it yourself on our sample repository: an online shop with its recommender and fraud model fenced off.
Or read how it works and the security details.