docs/sources/as-code/observability-as-code/git-sync/scenarios/testing-sandboxes.md
Use a sandbox branch that users can push to directly, without opening a pull request for every change. A sandbox branch is a low-friction space for short-lived projects and experimentation, while keeping every dashboard version-controlled in Git. When work is ready, you promote it to the main branch.
A sandbox is a branch in the same repository, synced to Grafana with the write workflow enabled. With the write workflow, saving a dashboard commits directly to the sandbox branch, so the editing experience feels close to using Grafana without Git Sync. The difference is that every change is still committed to Git, so nothing is lost and history is preserved.
This scenario uses a single shared sandbox branch that everyone works in. A shared sandbox uses only one Repository connection regardless of how many users work in it, which keeps you well within the per-stack limit of 10 repository connections. If you need stricter isolation, you can instead give each user their own sandbox branch. Refer to Individual or shared sandboxes.
main branch.┌────────────────────────────────────────────────────────────┐
│ GitHub Repository │
│ Repository: your-org/grafana-manifests │
│ │
│ Branch: main ← Promoted, reviewed work │
│ └── grafana/ │
│ ├── dashboard-stable.json │
│ └── dashboard-approved.json │
│ │
│ Branch: sandbox ← Direct pushes, shared experiments │
│ └── grafana/ │
│ ├── alice/dashboard-wip.json │
│ └── bob/dashboard-test.json │
└────────────────────────────────────────────────────────────┘
↕
Git Sync (write workflow)
↕
┌─────────────────────────┐
│ Grafana Instance │
│ │
│ Repository Resource: │
│ - branch: sandbox │
│ - path: grafana/ │
│ - workflows: [write] │
│ │
│ Save = direct commit │
│ to sandbox │
└─────────────────────────┘
In Git:
your-org/grafana-manifests
├── (branch: main)
│ └── grafana/
│ ├── dashboard-stable.json
│ └── dashboard-approved.json
└── (branch: sandbox)
└── grafana/
├── alice/
│ └── dashboard-wip.json
└── bob/
└── dashboard-test.json
In Grafana Dashboards view (synced to sandbox):
Dashboards
└── 📁 grafana-manifests/
├── 📁 alice/
│ └── Work in Progress Dashboard
└── 📁 bob/
└── Test Dashboard
alice/ and bob/, to keep their work separate within the shared branch. Subfolders map to subdirectories under the synced path, so no extra Repository connection is needed.Configure the Repository resource to sync with the sandbox branch and enable the write workflow:
your-org/grafana-manifestssandboxgrafana/writeIn the Repository resource, this looks like:
spec:
github:
url: 'https://github.com/your-org/grafana-manifests'
branch: 'sandbox'
path: grafana/
workflows:
- write
{{< admonition type="note" >}}
If you enable only the write workflow, saving a dashboard always commits directly to the sandbox branch. To also allow users to open pull requests from Grafana, add the branch workflow: workflows: [write, branch]. Refer to Configuration parameters for details.
{{< /admonition >}}
sandbox.write workflow enabled.main branch. Refer to Promote a sandbox to main.A sandbox can be shared by everyone or scoped to a single user. Each sandbox is a branch synced through its own Repository connection, so the choice is shaped by the per-stack limit of 10 repository connections. Refer to Usage and performance limitations for details.
sandbox, synced through one Repository connection that all users share. This uses only one connection regardless of how many users work in it, so it scales to any number of users. Separate users' work with subfolders (for example, alice/, bob/) if you want some organization within the shared branch. The trade-off is less isolation, since everyone commits to the same branch. This is the setup described above.sandbox/alice and sandbox/bob, each synced through a separate Repository connection. This provides the most isolation, but every sandbox consumes one of your 10 connections, so per-user sandboxes don't scale to many users. Reserve them for a small number of active users or short-lived projects, and delete the branch and its connection when the work is done to free the connection.Both approaches promote to main the same way. Refer to Promote a sandbox to main.
Even though sandbox branches allow direct pushes, protect them against destructive operations. We recommend blocking force pushes on sandbox branches in your Git provider.
Force pushes rewrite branch history and can silently discard commits that Git Sync relies on. Blocking them keeps history append-only, so Grafana and Git stay consistent and you can always trace how a dashboard reached its current state.
sandbox or the pattern sandbox/* if you use individual sandboxes) and disable Allow force pushes.You typically keep pull requests optional on sandbox branches so users can push directly, while still blocking force pushes.
When sandbox work is ready, promote it to the main branch. Because everything already lives in Git, promotion is a standard Git operation. Choose the option that fits your review requirements:
Use your Git provider to open a pull request from the sandbox branch into main.
sandbox into main.main picks up the promoted dashboards on its next sync.This keeps a full review and audit trail for everything that reaches main, and is the recommended path when main feeds production.
If you also enable the branch workflow on the sandbox Repository resource, users can open these pull requests directly from Grafana when they save, instead of switching to the Git provider.
When only some dashboards are ready, promote them selectively instead of merging the whole branch.
main, or copy the specific dashboard files.main and review it.Use this when a shared sandbox contains a mix of finished and experimental work.
When main is synced to a production instance, treat the sandbox as the development stage of a promotion flow.
write workflow).main using a pull request (Option 1) or by copying files into the main path.main updates automatically.This mirrors the development and production environments scenario, with the sandbox branch acting as the development stage.
If the main branch is synced to a folder in the same instance (through a second Repository connection) or to a separate instance, users can move a dashboard into it directly from Grafana, without touching Git:
main branch as the destination. Git Sync commits the copy to main.main branch. Git Sync commits it to main.This suits users who prefer working entirely in the UI. Note that these paths commit to main without a pull request, so use them only when main allows direct writes; when main requires review, prefer Option 1.
After promotion, you can delete short-lived sandbox branches, or keep a long-lived shared sandbox and continue iterating.
Refer to the following documents to learn more: