aem-eds-kit / Secure GitHub sandboxes

Security guide

Secure GitHub sandboxes

eds sandbox creates throwaway EDS repos on GitHub and tears them down in seconds. This guide shows how to authorize GitHub with least privilege, so the token you give the CLI can only ever see the repo you are building - and nothing else in your account.

●Fine-grained token ●Only your sandboxes ●Stored owner-only (0600)

The goal: only this repo, never the others

The safest setup is one where the GitHub credential the CLI holds can touch only your sandbox repos. GitHub's fine-grained personal access tokens make that possible - but there is one rule that shapes everything below:

✦

You cannot scope a token to a repo that does not exist yet. Creating a repository is an account- or organization-level action. So "limit to one repo" and "create new repos" need slightly different setups.

Two setups, depending on what you need

You want to…SetupWhat the token can see
Manage one existing sandboxFine-grained token → Only select repositories → pick that one repoExactly that repo. Nothing else.
Create new sandboxesFine-grained token → Resource owner: a dedicated sandbox org → All repositories (in that org)Only repos in that org. Your personal account and other orgs stay invisible.

Setup A - lock a token to a single repo

Best for working on one sandbox that already exists (list, rm, pushing code):

  1. Open github.com/settings/personal-access-tokens/new.
  2. Repository access → Only select repositories → choose the one sandbox repo.
  3. Permissions → set the minimum below.
  4. Set a short expiry (e.g. 7 or 30 days).
  5. Generate, copy, then run eds sandbox login and paste it.

This token literally cannot read or write any other repository - GitHub enforces it server-side.

Setup B - a dedicated sandbox org for new repos

Best when you want to keep spinning up fresh sandboxes without ever exposing your real repos. Because creation is an account-level action, you isolate it by giving the token its own container:

  1. Create a free GitHub organization, e.g. my-sandboxes (Settings → Organizations → New).
  2. Open github.com/settings/personal-access-tokens/new.
  3. Resource owner → select my-sandboxes (not your personal account).
  4. Repository access → All repositories (this means all repos in that org only).
  5. Permissions → set the minimum below.
  6. Set a short expiry, generate, and eds sandbox login.
  7. Always pass the org: eds sandbox new my-test --org my-sandboxes.
✦

With this token, your personal account and every other organization are completely invisible - it can only create, read, and delete repos inside my-sandboxes. This is the cleanest way to satisfy "nothing else, ever".

Minimum permissions

Grant only these three repository permissions - nothing more:

PermissionLevelWhy
AdministrationRead and writeCreate a repo from a boilerplate, set its topic, and delete it
ContentsRead and writeClone and push code to the sandbox
MetadataReadMandatory baseline GitHub requires for any fine-grained token

Fine-grained token vs. OAuth Device Flow

eds sandbox login supports two paths:

For the tightest blast radius, prefer the fine-grained token.

What the CLI itself touches

Independent of the token's scope, aem-eds-kit is deliberately narrow in what it ever does on GitHub:

Where the token is stored

After login, the token is written to ~/.eds/github.json with owner-only permissions (mode 0600, directory 0700) - the same convention gh and npm use. It never enters your project or git history. Remove it any time:

$ eds sandbox logout                 # deletes the stored token

You can also revoke the token itself on GitHub → Settings → Developer settings → Personal access tokens (or Authorized OAuth Apps for the device flow).

Quick start

$ eds sandbox login                  # paste a fine-grained token
$ eds sandbox new my-test --org my-sandboxes   # isolated in the org
$ eds sandbox list                   # only eds-sandbox repos
$ eds sandbox rm my-test             # confirmed teardown

FAQ

Can I give the token access to only one GitHub repository?

Yes. Create a fine-grained personal access token with Repository access → Only select repositories and choose that single repo. The token cannot read or write any other repository - GitHub enforces this on the server. This works for an existing repo; to create a new one, use a dedicated sandbox org instead.

Why can't a token be scoped to a repo I'm about to create?

Creating a repository is an account- or organization-level action, and you cannot select a repository that does not exist yet. The clean workaround is a dedicated sandbox organization: scope the token to that org, and it can only ever touch repos inside it.

Is the OAuth Device Flow safe?

Yes. You authorize in the browser on github.com, so the CLI never sees your password, and it only ever talks to github.com. The trade-off is scope: OAuth apps use account-wide classic scopes, so for the narrowest access, a fine-grained token scoped to specific repos or one org is tighter.

What permissions does the token actually need?

Only three, all repository-level: Administration (Read and write) to create/tag/delete the repo, Contents (Read and write) to clone and push, and Metadata (Read), which GitHub requires on every fine-grained token.

Where is my token stored and how do I remove it?

In ~/.eds/github.json with owner-only permissions (mode 0600). Run eds sandbox logout to delete it, and revoke it on GitHub under Settings → Developer settings for good measure.

Is deleting a sandbox reversible?

No. eds sandbox rm permanently deletes the repository, so it always asks for confirmation first (defaulting to No). Keep sandboxes public and disposable, and tear them down when you are done.

eds sandbox reference →   Document Authoring vs Universal Editor →