Documentation
Source control guide

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.

Git smart HTTPGit LFSPrivate by default
Start hereOrganization › Projects › project › Code
Write permissionProject-scoped Manage source
Successful resultAn Active repository with a working HTTPS clone
01 / Before you begin

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 Manage source 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.

02 / Create

Create an empty repository.

Organization›Projects›project›Code›Repository
  1. Open Code.Select the organization and project that will own the repository, then choose Repository.
  2. Name the repository.Enter a display name and review the generated slug. The slug becomes part of the browser and HTTPS Git URL.
  3. Add a description.The rich-text description is optional and can be revised later from repository Settings › General.
  4. 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.

03 / Local Git

Clone, fetch, and push over HTTPS.

Code›repository›Clone

The Clone dialog displays the authoritative URL. Its shape is:

Terminalreplace the organization and repository slugs
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
  1. 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.
  2. 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.
  3. 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.
  4. Verify the remote.Run git remote -v and 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.
Transport available today

Mozaic supports Git smart HTTP and Git LFS over HTTPS. SSH Git transport is not part of the current product path.

04 / Import

Import a verified Git bundle.

Organization›Projects›project›Code›Import 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.

Terminalfrom the source repository
git bundle create repository.bundle --all
git bundle verify repository.bundle
  1. Select the bundle.The file must be a valid Git bundle and must contain refs/heads/main.
  2. Enter repository details.Provide the name, slug, and optional description. Imported repositories also start private.
  3. 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 Provision source can upload the same verified bundle without browser cookies. Add Manage projects 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.

metadata.jsonprivate import
{
  "slug": "utf",
  "name": "United Tactical Forces",
  "description": {"markdown": "Imported project", "dialect_version": 2},
  "visibility": "private"
}
Terminalcredential supplied by a private helper
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.

05 / Browser workspace

Browse history and make bounded edits.

Code›repository›Files / Commits / Compare
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.

06 / Fork

Fork into an explicit organization and project.

Code›repository›Fork
  1. Choose the target.Select an organization and project where you have Manage source. There is no hidden personal fork namespace.
  2. Review repository details.Mozaic suggests a fork name and slug. Change them if the target project already uses that slug.
  3. Confirm the source relationship.The Review step names the source repository, target owner, slug, and initial private access.
  4. 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.

07 / Credentials

Choose scoped credentials for people or automation.

Code›repository›Settings›Credentials

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 Provision source and Authorize pipeline triggers. 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.
  1. Name the client.Use a recognizable name such as Work laptop or Release workstation.
  2. Choose scopes and expiry.The default is 90 days. The accepted range is 1-365 days.
  3. Copy the token immediately.The raw secret is returned once. Mozaic stores its digest, not a retrievable copy.
  4. Revoke unused credentials.The list shows active, expired, and revoked credentials plus last-use time when available.
Per-user limit

Each user can have at most 32 active credentials for one repository. Revoke an old credential before issuing another when the limit is reached.

08 / Lifecycle and public access

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.

Code›repository›Settings›Lifecycle
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.
  1. Export first.Choose Export all refs to download a verified Git bundle independent of archive state.
  2. Archive.This is reversible. Confirm that expected clones can still fetch and that automation no longer needs to push.
  3. Reactivate if needed.An Archived repository can return to Active without changing its identity.
  4. 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.

Current UI boundary

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.

09 / Limits and security

Know the enforced boundaries.

BoundaryCurrent behavior
Repository slug1-100 characters with an alphanumeric first and last character. New-repository creation accepts lowercase letters, digits, and hyphens; bundle import also accepts underscores.
Repository name1-180 characters.
Description16 KiB maximum.
Git HTTPS request1 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 lifetime1-365 days; 90 days by default.
Active credentials32 per user per repository.
Git transportHTTPS smart HTTP and Git LFS; no SSH Git transport.
ImportVerified 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.
10 / Troubleshooting

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.