1---
2title: Authentication and authorization
3description: Use native Effect HTTP middleware and ordinary application effects to authorize Git operations.
4---
5
6Your application owns users, credentials, and authorization. Git's binary protocol
7runs over HTTP, so native Effect API middleware also applies to push and fetch.
8
9## Provide the request's user
10
11```typescript
12class Authentication extends HttpApiMiddleware.Service<
13 Authentication,
14 { provides: CurrentUser }
15>()("app/Authentication", { error: Unauthorized }) {}
16
17class AppApi extends HttpApi.make("app")
18 .addHttpApi(Git.Api)
19 .middleware(Authentication) {}
20```
21
22Supply `Authentication` with an ordinary layer. Its implementation resolves a
23credential and provides `CurrentUser` while running the endpoint effect. Build
24Git groups with `HttpApiBuilder.group(AppApi, ...)`, so their endpoint metadata
25includes this middleware. The [complete example](https://github.com/alchemy-run/alchemy/tree/main/examples/cloudflare-git-service/src/api/middleware.ts)
26uses Better Auth sessions and API keys this way.
27
28`handleRaw` skips automatic payload decoding; it still runs API middleware.
29Your custom push handler can yield the same user and database services as a JSON
30handler. [Engine operations](/git/blocks/engine) shows the decode/prepare/commit flow.
31
32## Authorize proposed changes
33
34Middleware can authorize repository access before reading a pack. Once the
35handler decodes ref commands, call application policy functions. After preparing
36a push, validate its staged objects. Only then commit.
37
38| Boundary | Application decision |
39| --- | --- |
40| Before decoding | May this caller read or write this repository? |
41| After decoding commands | May these refs be created, moved, or deleted? |
42| After preparing objects | Are the incoming commits and files acceptable? |
43
44Policies can use typed errors and services. They are ordinary Effects, split into
45modules and called in sequence. Apply shared write policies to push, REST ref
46updates/deletions, and REST/GitHub pull merges; authorizing one endpoint does not
47authorize or protect the others.
48
49## Git credentials and public repositories
50
51Git sends HTTP Basic with the credential in the password field.
52`HttpApiBuilder.securityDecode(HttpApiSecurity.basic)` reads it. Return a `401`
53with `WWW-Authenticate: Basic realm="git"` when credentials are needed.
54
55`Git.isRead(request)` recognizes REST reads, upload-pack, and fetch advertisements.
56Receive-pack advertisements are writes. Resolve the repository before allowing
57anonymous reads, according to your application's public-repository policy.
58
59## Router middleware is also supported
60
61The tutorial introduces `HttpRouter.middleware` first. It can provide a typed
62`Session` service across both Git and application routes:
63
64```typescript
65const PublicRoutes = Layer.mergeAll(AppApiLive, Git.ApiLive).pipe(
66 Layer.provide(Authentication.layer),
67);
68```
69
70This `Authentication` is the tutorial's router middleware descriptor. Router
71middleware does not add error schemas to `Git.Api`. Declare application errors
72on your API when clients need to decode them. Native API middleware, as in the
73first example, carries both its provided services and its error schemas.
74
75## Internal hashing
76
77Mount `Git.InternalApiLive` outside application authentication. Its handler
78checks its own internal secret; user credentials do not authorize internal hashing.