Concepts
Git credential helper contract (setup-git)
Official Kody doc
This page is the server contract for the CLI kody auth setup-git command
(implemented in packages/cli). Persistent HTTPS auth like GitHub's credential
helper: after one setup, clone/pull/push over plain
https://kody.codes/@owner/name.git with no re-auth. SSH is out of scope.
Origin requirements
kody auth setup-git installs the helper only when the origin advertises
user-owned tokens:
If org_binding is absent on token metadata, the CLI refuses to install the
helper. There is no gitCredentialMint and no POST /v1/git/credentials.
User-owned API tokens
Behavior
| Token | Org on each request | Leaving an org |
|---|---|---|
org_binding: "org" (tokenCreate default) | Fixed org_id on the token row. Ignore ?org=. | Org-bound tokens for that org are revoked on leave. |
org_binding: "user" (CLI bootstrap default) | ?org=<slug-or-id>; omit → personal org. | Token stays; membership/grant checks deny immediately. |
The same kody_at_… token covers Open API, CapabilityProxy / local execute, and
git HTTPS. Scopes still narrow every call. Revoke with tokenRevoke /
token:delete (or account token UI); git stops accepting it on the next
request.
Request org selection
- HTTP Open API / CapabilityProxy: query parameter
?org=<slug>(or org id). Do not sendX-Kody-Org— the API edge does not forward custom headers. - Default: personal org (person
stable_user_id). - Errors: inaccessible or unknown
org→401 unauthorizedwith a message that names?org=. - Git HTTPS: there is no
?org=on the git URL. Authz is user-wide across orgs: the login / MCP org never gates git. Access uses the resource owner's org (membership or live grant) plus the token's scopes. Onesetup-gitcredential (org_binding: user) must open every@owner/name.gitthe person can already access in any org. API / MCP calls for@ownerpackages still need?org=/--orgwhen acting in that org.
Minting
cliCredentialBootstrap/ redeem: mintsorg_binding: "user". Redeem honors the binding stamped on the code.tokenCreate: defaults toorg(current request org). Pass"org_binding": "user"for a person-owned token. An org-bound parent token cannot mint a user-owned child.
Persistent git credentials (credential helper)
kody auth setup-git installs a credential helper that stores the user's
long-lived kody_at_… (same token as execute/API). Git sends it on every
request; the origin checks it every request. There is no short-lived
kody_gt_… mint and no POST /v1/git/credentials.
CLI credential helper output for git:
username=x
password=kody_at_…Username may be any non-empty string (convention: x). Password is the full API
token. Store it in the helper / OS keychain the CLI configures — same longevity
as the API token (idle/max lifetime; slid on use).
Git config installed by kody auth setup-git (CLI side):
git config --global credential.https://kody.codes.helper '!kody git-credential'
# ensure path is sent:
git config --global credential.https://kody.codes.useHttpPath trueAuthenticated git HTTP
Canonical URL:
https://kody.codes/@owner/name.gitPlain repos need org-wide package:read / package:write (same as
repoGetGitRemote). A single-package grant does not open every plain repo under
that owner.
Push semantics
- Plain repos: push updates live HEAD (same as Artifacts write remotes from
repoGetGitRemote). - Packages: push moves live HEAD only. It does not auto-publish; publish stays an explicit package action.
- Access default: mint an Artifacts write token when the caller can write, otherwise read.
Authz
Caller must:
- Hold
package:read(clone/fetch) orpackage:write(push) on the API token scopes. Scopes have no hierarchy (package:writedoes not imply read). - Be able to access the target via org membership or a live grant on the
resource owner's org — not the MCP / API login org. Git is user-wide; a
missing package and a private package the caller cannot access both look like
404 repository not found.
Name collision: if both a package and a plain repo exist under the same
@owner/name, a readable package wins.
Out of scope (this contract)
- SSH
- Changing public anonymous snapshot semantics
- Forced migration of existing org-bound
kody_at_…tokens - Auto-publish on package push
