Git repositories
Create or import an organization-owned repository, connect a local Git client over HTTPS, and manage its credentials and lifecycle without blurring project ownership.
Choose the project and the access you need.
Prerequisites
- A verified Mozaic account and membership in the organization.
- An existing project to own the repository. Mozaic does not create personal repositories outside an organization.
- The claim at the project or organization scope to create, import, fork, edit, push, archive, reactivate, or delete.
- Git installed locally for clone, fetch, and push. Git LFS is optional and uses the same repository URL and separately scoped token permissions.
Any project member can browse an Active or Archived repository. A signed-in non-member can read only a repository whose organization, project, and repository have all been explicitly published.
Create an empty repository.
- Open Code.Select the organization and project that will own the repository, then choose Repository.
- Name the repository.Enter a display name and review the generated slug. The slug becomes part of the browser and HTTPS Git URL.
- Add a description.The rich-text description is optional and can be revised later from repository Settings › General.
- Create it.Mozaic reserves the identity, provisions Git storage, and then moves the repository to
Active. Creation always requests private visibility.
Success state
The repository appears in Code with lifecycle Active, default branch refs/heads/main, Git object format sha1, and reftable reference storage. You can open Files, Commits, Compare, Pull requests, or Settings.
Names contain 1-180 characters. A new repository slug contains lowercase letters, digits, and hyphens, beginning with a letter or digit. Bundle-import slugs may also contain underscores. The server limit is 100 characters. Descriptions are limited to 16 KiB.
Clone, fetch, and push over HTTPS.
The Clone dialog displays the authoritative URL. Its shape is:
git clone https://<organization-slug>.mozaic.space/git/<organization-slug>/<repository-slug>.git
# Connect an existing local repository
git remote add origin https://<organization-slug>.mozaic.space/git/<organization-slug>/<repository-slug>.git
git branch -M main
git push -u origin main
- Review the organization policy.Open More information in the Clone dialog. For personal Mozaic accounts, browser OAuth may be required; an organization can allow verified Mozaic email and password access only when compatible with its identity and action policies. Company SSO identities use organization-bound credentials after company sign-in.
- Configure browser OAuth once when required.Apply the Git Credential Manager commands shown by Mozaic for this exact organization host. The next private Git operation opens the browser.
- Verify identity.If a new OAuth credential requires fresh authentication, the browser opens Mozaic's focused verification page. Complete a passkey, security key, authenticator code, or the recovery-code fallback. Mozaic then returns to Git authorization.
- Verify the remote.Run
git remote -vand then fetch or push. Git Credential Manager stores the resulting OAuth token in the operating-system credential store; do not put passwords or tokens into the URL, shell history, or committed Git configuration.
Mozaic supports Git smart HTTP and Git LFS over HTTPS. SSH Git transport is not part of the current product path.
Import a verified Git bundle.
Import is a one-time transfer, not an ongoing mirror. Produce a bundle locally, then upload it through the Source, Details, and Review steps.
git bundle create repository.bundle --all
git bundle verify repository.bundle
- Select the bundle.The file must be a valid Git bundle and must contain
refs/heads/main. - Enter repository details.Provide the name, slug, and optional description. Imported repositories also start private.
- Review and import.Mozaic streams the upload into quarantine, verifies it, and finalizes it atomically. Do not navigate away while the transfer is in progress.
Success state
The repository changes from Provisioning to Active and the imported branches, tags, and history are available. If validation fails, the lifecycle is Provisioning failed; no partially imported repository becomes writable.
Import through the scoped automation API
A tenant-issued PAT with can upload the same verified bundle without browser cookies. Add only when automation must also create the destination project. Issue the delegation through Settings › Access › API tokens with fresh MFA. Platform operators cannot mint it for the user.
Use POST /api/v1/organizations/{organization_id}/projects/{project_id}/repositories:import with exactly two multipart fields: metadata containing typed JSON and bundle containing the Git bundle. Import creates the repository directly; do not first create an empty repository with the same slug. It retains browser import's quarantine, verification, scanning, size limits, storage accounting, authorization and audit.
If the import reaches Provisioning failed, correct the bundle and use POST /api/v1/organizations/{organization_id}/repositories/{repository_id}/import-retries to keep the same repository ID and slug. Supply a complete bundle and matching repository metadata as the two multipart fields, the failed repository's current version in If-Match, and a fresh Idempotency-Key. The request needs the same project-scoped source management permission as a new import. Replaying the key with different bundle bytes is rejected. The earlier failed operation stays in history.
{
"slug": "utf",
"name": "United Tactical Forces",
"description": {"markdown": "Imported project", "dialect_version": 2},
"visibility": "private"
}
curl --config /private/mozaic-api.curl --proto '=https' --fail-with-body \
--header 'Idempotency-Key: import-utf-v1' \
--form 'metadata=@metadata.json;type=application/json' \
--form 'bundle=@repository.bundle;type=application/octet-stream' \
'https://TENANT.mozaic.space/api/v1/organizations/ORGANIZATION_ID/projects/PROJECT_ID/repositories:import'
The owner-only curl configuration supplies the Authorization: Bearer header; never put the token in argv, URLs, public environment, or logs. Reuse the same idempotency key, metadata and exact bundle bytes after an ambiguous response. A changed payload with the same key is rejected. Successful replay returns the same repository. The existing refs/heads/main requirement still applies. This delegation does not grant Git transport, Git credential issuance, pipeline execution or publication; import does not implicitly approve or run imported code.
Browse history and make bounded edits.
- Files
- Browse a selected revision, open UTF-8 source, inspect directories, history and blame, and use browser editing when the repository is Active and you hold Manage source.
- Commits
- Select a full branch or tag reference, page through its history, and inspect commit signature evidence.
- Compare
- Choose exact base and head references. The result records the resolved revisions and displays the textual patch.
- Pull requests
- Open or review a proposal whose source, target, and merge base are pinned into an immutable snapshot.
Browser edits compare the expected revision before updating a ref. If another writer moves the branch first, reload the latest revision and reapply the change instead of overwriting it.
Select the default branch
New and imported repositories initially use refs/heads/main. In repository Settings › General › Default branch, a source manager can select an existing branch and save it. Complete the MFA verification prompt when requested. The same fresh-MFA browser session can select a branch using PUT /api/v1/organizations/{organization_id}/repositories/{repository_id}/default-branch, a JSON body such as {"reference":"refs/heads/master"}, and the session CSRF token, If-Match repository version and Idempotency-Key. The branch must already exist; the operation neither renames branches nor rewrites commits. Git clone discovery and trusted pipeline triggers use the selected branch. Selecting a branch does not schedule a run.
The previous default keeps its effective review policy. An explicit policy on the selected branch remains authoritative; otherwise normal default-branch protection applies. The selected default and historical main both reject deletion and non-fast-forward native pushes. If Git HEAD reconciliation fails after the metadata commit, retry the same command; Git discovery also repairs HEAD from committed metadata.
Governed direct pushes
Main requires pull-request admission by default. An authorized owner can explicitly configure one repository for direct pushes to its default branch without changing that global default. The native receive guard still rejects deletion and non-fast-forward updates to refs/heads/main. Direct push permission does not grant deployment authority.
Automation can GET and PUT /api/v1/organizations/{organization_id}/repositories/{repository_id}/branch-policy?reference=refs%2Fheads%2Fmain with a tenant PAT that independently delegates both Provision source and Authorize pipeline triggers. The issuer must still hold both organization claims and Manage source for the repository's project. PAT access is limited to the current default branch and cannot enable bypass. Use its full URL-encoded reference in the query. Browser policy updates retain fresh MFA and CSRF.
GET returns the effective policy and its ETag. Copy the policy object, preserve commit-signature settings and allowed merge strategies, then deliberately change the intended requirements. PUT the complete policy with the GET ETag in If-Match. A 412 requires reloading and reviewing the latest policy. After a lost response, GET again and compare the entire policy before retrying. Existing policy audit history is retained.
Fork into an explicit organization and project.
- Choose the target.Select an organization and project where you have Manage source. There is no hidden personal fork namespace.
- Review repository details.Mozaic suggests a fork name and slug. Change them if the target project already uses that slug.
- Confirm the source relationship.The Review step names the source repository, target owner, slug, and initial private access.
- Create the fork.Wait for the new repository to become Active, create a branch, push your change, and then open a pull request against the original repository.
Forking is also the supported contribution path from a public repository: authenticate, place the fork in an organization you control, and keep ownership visible throughout review.
Choose scoped credentials for people or automation.
Repository-scoped, show-once credentials default to human use. Choose the credential purpose in the creation form; human use is the default. Sign in to the organization before issuing a credential. A human credential is bound to that organization and its issuing session; logout or session rotation requires a replacement credential. Credential creation requires the organization action policy to be satisfied, with fresh MFA required by default. A member can issue read-only credentials for their own use. A credential containing either write scope additionally requires Manage source.
For CI or other unattended automation, choose the explicit machine purpose when issuing the credential (or request purpose: "machine" through the API). This additionally requires organization administration and the existing repository permissions. Machine credentials retain their scopes, expiry, revocation and current owner access checks, and each action can disallow machine access. Naming a credential after a service or using a Git endpoint does not make it an automation credential.
Human credentials are checked against the current action policy on use, including provider revalidation and MFA evidence. The selected token expiry is an upper limit; it does not extend the issuing session or guarantee access for that duration. Previously issued personal credentials without session evidence can satisfy only actions that require no MFA, in organizations that still accept personal accounts.
Issue personal access tokens from a personal-account organization session with fresh local MFA. Company/provider-only sessions cannot issue PATs. PATs retain human purpose and the exact organization session that issued them. They do not receive a machine-policy exception. Current action policy, provider status and session evidence are checked on every use; logout, session rotation or revoked provider access can require replacement. Legacy tokens without session evidence cannot satisfy actions that require that evidence.
API-only onboarding can use a fresh-MFA-issued PAT with both and . Call POST /api/v1/organizations/{organization_id}/repositories/{repository_id}/credentials with a stable idempotency key and a body such as {"name":"Initial governed push","scopes":["git_read","git_write"],"expires_in_days":1}. Both current project source and pipeline authority are checked. The issued credential is bound to this repository and expires no later than the PAT; PAT requests cannot delegate LFS scopes. Use username git and the returned show-once token through a private credential helper.
After importing and registering the pipeline, push the intended reviewed changes through the normal protected-branch or pull-request workflow. An unchanged push does not trigger a run. Branch checks, review requirements and actual accepted-ref evidence still apply; import and manual scheduling do not create trusted publication authority. Revoke the provisioning PAT and the independently issued Git credential after onboarding.
git_read- Clone and fetch Git objects.
git_write- Push Git refs. This scope is valid only together with
git_read. lfs_read- Download Git LFS objects.
lfs_write- Upload LFS objects and create or release LFS locks. This scope is valid only with
lfs_read.
- Name the client.Use a recognizable name such as
Work laptop
orRelease workstation
. - Choose scopes and expiry.The default is 90 days. The accepted range is 1-365 days.
- Copy the token immediately.The raw secret is returned once. Mozaic stores its digest, not a retrievable copy.
- Revoke unused credentials.The list shows active, expired, and revoked credentials plus last-use time when available.
Each user can have at most 32 active credentials for one repository. Revoke an old credential before issuing another when the limit is reached.
Archive before you delete.
To move current project containment, open repository Settings → General → Review project transfer. The existing project-settings workflow verifies the exact repository UUID, destination access and bounded dependencies before fresh-MFA confirmation. Current navigation follows the returned current project; recorded origin, Git/LFS identity, review snapshots and historical pipeline attribution stay unchanged. Review the transfer workflow and restrictions.
Recorded-origin repository slugs remain reserved: moving current containment does not free the original name. Use an alternate name when a retained native identity reserves the slug. Stable repository-UUID clone addresses and registry-UUID package endpoints keep their native identity. Current operations require current destination permissions; old project grants and old-generation credentials do not authorize the moved resource. Reissue or review scoped credentials against current containment and its generation instead of copying credentials. Review snapshots, run execution context and publication provenance remain historical evidence, separate from current permissions.
Whole-project merges retain a read-only source notice. Repository, complete NuGet identity and complete OCI repository transfers are supported; NPM, Maven and Debian contributors are unsupported and block a merge when present. Resolve returned blockers before confirming; unsupported content is never silently skipped.
- Active
- Readable and writable, subject to credentials, claims, and branch policy.
- Archived
- Read-only. Browse, clone, fetch, existing reviews, and verified bundle export remain available. Push, browser edits, review mutations, and write credentials are rejected.
- Deleted
- Repository bytes are removed. Identity, actor, reason, and lifecycle history remain as an audit tombstone.
- Export first.Choose Export all refs to download a verified Git bundle independent of archive state.
- Archive.This is reversible. Confirm that expected clones can still fetch and that automation no longer needs to push.
- Reactivate if needed.An Archived repository can return to Active without changing its identity.
- Delete only when required.Enter an audited reason and type the repository slug exactly. Byte deletion is permanent; the tombstone is not.
Public access has three gates
Anonymous repository reads require an explicitly public organization, an explicitly published project, and a public repository. A public child never makes a private parent public. New repositories and imports begin private.
Repository Settings › Access shows the repository's publication state, but that state is informational and read-only in the current workspace. Project Settings › Public access governs the project gate; it does not inventory repositories or prove that this repository is public.
Know the enforced boundaries.
| Boundary | Current behavior |
|---|---|
| Repository slug | 1-100 characters with an alphanumeric first and last character. New-repository creation accepts lowercase letters, digits, and hyphens; bundle import also accepts underscores. |
| Repository name | 1-180 characters. |
| Description | 16 KiB maximum. |
| Git HTTPS request | 1 GiB maximum per smart HTTP request, including an initial native-history push. Requests are staged to disk and remain subject to organization storage limits. Use Git LFS for large files. |
| Credential lifetime | 1-365 days; 90 days by default. |
| Active credentials | 32 per user per repository. |
| Git transport | HTTPS smart HTTP and Git LFS; no SSH Git transport. |
| Import | Verified Git bundle containing refs/heads/main; upload size is bounded by the operated installation. |
- Keep tokens out of URLs, commits, logs, screenshots, and issue descriptions.
- Use separate credentials for separate devices or automation so each can be revoked independently.
- A push is checked against the exact target ref and branch policy; a valid write token does not bypass review rules.
- Repository operation history and description revisions are retained even when current prose or bytes change.
Resolve common failures.
The repository is Provisioning or Provisioning failed
Files and Git transport are available only after lifecycle Active. Return to Code to inspect the state. For a failed import, correct the bundle and use the versioned retry-import API to retain its repository ID and slug. A separate new import needs a different slug. If an earlier attempt published Git bytes before failing, the retry bundle must resolve to the same branches and tags; a mismatch requires operator diagnosis.
Git returns authentication failed
For browser OAuth, confirm that Git Credential Manager is configured for the exact organization host and retry after completing the browser flow. For an organization that accepts personal accounts and permits password access under the current action policy, use your verified Mozaic email and account password. For a repository-scoped credential, use username git and confirm that the token is unexpired, unrevoked, bound to this repository, and has the required scopes. Human credentials also need a current issuing session and the action’s required authentication evidence.
Every fetch opens another browser tab
Git Credential Manager should reuse the 30-day OAuth token saved by the operating-system credential store. Complete one verification flow, then confirm that a credential for the exact organization Git host was stored. Concurrent Git processes can open duplicate tabs before the first flow finishes; cancel the extras and retry after storage succeeds. Mozaic requires fresh MFA when issuing a new OAuth credential and checks the current organization policy on subsequent requests. A cached token cannot bypass action-specific MFA, provider revalidation, session expiry or revocation. OAuth credentials issued from an organization session remain bound to it. Legacy or control-issued personal OAuth credentials carry no MFA evidence and cannot authorize actions that require it; use a credential issued from an eligible organization session for those actions.
The verification window does not close itself
The verification popup closes automatically after successful verification and any workspace session handoff. If your browser prevents automatic closure, close the completed window and return to the original tab. Do not repeat the action while the original tab is still checking the updated session. Git authorization continues in its browser page instead of closing it.
Push is rejected although the token has Git write
The repository may be Archived, the target branch may require pull-request admission, or your effective role may no longer include Manage source. A token authenticates the user; it does not freeze authorization at issue time.
Bundle import says the default branch is missing
Verify the bundle locally and ensure it contains refs/heads/main. A bundle containing only a differently named branch is not accepted by the current import workflow.
An expected public repository returns not found
Check all three gates: organization, project, and repository. Mozaic intentionally returns not found when anonymous access is not authorized, rather than disclosing private resource existence.