feat: initial repo — docs and scripts for Gitea read-only token access
Three-layer access scheme: owner -> reader account -> scoped API token. Includes 6 automation scripts, config template, EN/RU docs, and manual curl guide. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
68
docs/architecture.md
Normal file
68
docs/architecture.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Architecture: Read-Only Token Access for Gitea
|
||||
|
||||
## Overview
|
||||
|
||||
This scheme provides controlled, minimal-privilege access to private Gitea repositories without sharing the owner's credentials.
|
||||
|
||||
## Components
|
||||
|
||||
```
|
||||
+-------------------+
|
||||
| Owner Account | Full admin access to Gitea
|
||||
| (e.g. aibot777) | Owns all repositories
|
||||
+--------+----------+
|
||||
|
|
||||
| Creates & manages via Admin API
|
||||
v
|
||||
+-------------------+
|
||||
| Reader Account | Restricted account ("hobo account")
|
||||
| (e.g. uclaude- | No admin rights
|
||||
| reader) | Can only access repos where explicitly
|
||||
+--------+----------+ added as collaborator (read permission)
|
||||
|
|
||||
| Authenticates via
|
||||
v
|
||||
+-------------------+
|
||||
| API Token | scope: read:repository
|
||||
| (sha1_xxx...) | Can only READ repos the reader
|
||||
+--------+----------+ account has access to
|
||||
|
|
||||
| Used by
|
||||
v
|
||||
+-------------------+
|
||||
| Scripts/Installers| git clone, curl, wget
|
||||
| CI/CD pipelines | Any tool that needs read access
|
||||
+-------------------+
|
||||
```
|
||||
|
||||
## Access Flow
|
||||
|
||||
1. **Owner** creates the reader account (one-time setup)
|
||||
2. **Owner** grants the reader access to specific repos (per-repo)
|
||||
3. **Reader's token** is used by automated tools to read those repos
|
||||
4. If the token leaks — revoke it, rotate, no owner credentials exposed
|
||||
|
||||
## Security Properties
|
||||
|
||||
| Property | Status |
|
||||
|----------|--------|
|
||||
| Owner credentials exposed | No |
|
||||
| Token can write to repos | No (read:repository scope) |
|
||||
| Token can access admin API | No |
|
||||
| Token can access repos not granted | No |
|
||||
| Token can be rotated independently | Yes |
|
||||
| Access is per-repo granular | Yes |
|
||||
|
||||
## Gitea API Endpoints Used
|
||||
|
||||
| Action | Method | Endpoint | Auth |
|
||||
|--------|--------|----------|------|
|
||||
| Create user | POST | `/admin/users` | Owner (admin) |
|
||||
| Activate user | PATCH | `/admin/users/{username}` | Owner (admin) |
|
||||
| Create token | POST | `/users/{username}/tokens` | Reader (basic) |
|
||||
| Delete token | DELETE | `/users/{username}/tokens/{name}` | Reader (basic) |
|
||||
| Add collaborator | PUT | `/repos/{owner}/{repo}/collaborators/{user}` | Owner |
|
||||
| Remove collaborator | DELETE | `/repos/{owner}/{repo}/collaborators/{user}` | Owner |
|
||||
| List repos | GET | `/user/repos` | Reader (token) |
|
||||
| Get repo | GET | `/repos/{owner}/{repo}` | Reader (token) |
|
||||
| Get raw file | GET | `/repos/{owner}/{repo}/raw/{path}` | Reader (token) |
|
||||
137
docs/manual-setup.md
Normal file
137
docs/manual-setup.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Manual Setup via curl
|
||||
|
||||
Step-by-step commands for setting up read-only access manually.
|
||||
Replace placeholders with your actual values.
|
||||
|
||||
## Variables
|
||||
|
||||
```bash
|
||||
GITEA_API="https://git.example.com/api/v1"
|
||||
OWNER="myuser"
|
||||
OWNER_PASS="mypassword"
|
||||
READER="myreader"
|
||||
READER_PASS="readerpassword"
|
||||
READER_EMAIL="myreader@noreply.local"
|
||||
```
|
||||
|
||||
## 1. Create Reader Account
|
||||
|
||||
```bash
|
||||
curl -X POST "$GITEA_API/admin/users" \
|
||||
-u "$OWNER:$OWNER_PASS" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "'"$READER"'",
|
||||
"password": "'"$READER_PASS"'",
|
||||
"email": "'"$READER_EMAIL"'",
|
||||
"must_change_password": false,
|
||||
"visibility": "public"
|
||||
}'
|
||||
```
|
||||
|
||||
Expected: HTTP 201
|
||||
|
||||
## 2. Activate Account
|
||||
|
||||
Some Gitea configurations require explicit activation:
|
||||
|
||||
```bash
|
||||
curl -X PATCH "$GITEA_API/admin/users/$READER" \
|
||||
-u "$OWNER:$OWNER_PASS" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"active": true,
|
||||
"visibility": "public",
|
||||
"login_name": "'"$READER"'"
|
||||
}'
|
||||
```
|
||||
|
||||
## 3. Create API Token
|
||||
|
||||
Authenticate as the reader to create a token with limited scope:
|
||||
|
||||
```bash
|
||||
curl -X POST "$GITEA_API/users/$READER/tokens" \
|
||||
-u "$READER:$READER_PASS" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "installer-readonly",
|
||||
"scopes": ["read:repository"]
|
||||
}'
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"name": "installer-readonly",
|
||||
"sha1": "abc123...",
|
||||
"token_last_eight": "abc12345"
|
||||
}
|
||||
```
|
||||
|
||||
Save the `sha1` value — it is only shown once.
|
||||
|
||||
## 4. Grant Access to a Repository
|
||||
|
||||
```bash
|
||||
REPO="my-private-repo"
|
||||
|
||||
curl -X PUT "$GITEA_API/repos/$OWNER/$REPO/collaborators/$READER" \
|
||||
-u "$OWNER:$OWNER_PASS" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"permission": "read"}'
|
||||
```
|
||||
|
||||
Expected: HTTP 204
|
||||
|
||||
## 5. Verify Access
|
||||
|
||||
With token (should work):
|
||||
```bash
|
||||
TOKEN="abc123..."
|
||||
|
||||
curl -H "Authorization: token $TOKEN" \
|
||||
"$GITEA_API/repos/$OWNER/$REPO"
|
||||
```
|
||||
|
||||
Without token (should return 404 for private repo):
|
||||
```bash
|
||||
curl "$GITEA_API/repos/$OWNER/$REPO"
|
||||
```
|
||||
|
||||
## 6. Clone with Token
|
||||
|
||||
```bash
|
||||
git clone "https://$READER:$TOKEN@git.example.com/$OWNER/$REPO.git"
|
||||
```
|
||||
|
||||
Or download a specific file:
|
||||
```bash
|
||||
curl -H "Authorization: token $TOKEN" \
|
||||
"$GITEA_API/repos/$OWNER/$REPO/raw/README.md"
|
||||
```
|
||||
|
||||
## 7. Revoke Access
|
||||
|
||||
Remove from collaborators:
|
||||
```bash
|
||||
curl -X DELETE "$GITEA_API/repos/$OWNER/$REPO/collaborators/$READER" \
|
||||
-u "$OWNER:$OWNER_PASS"
|
||||
```
|
||||
|
||||
## 8. Rotate Token
|
||||
|
||||
Delete old:
|
||||
```bash
|
||||
curl -X DELETE "$GITEA_API/users/$READER/tokens/installer-readonly" \
|
||||
-u "$READER:$READER_PASS"
|
||||
```
|
||||
|
||||
Create new:
|
||||
```bash
|
||||
curl -X POST "$GITEA_API/users/$READER/tokens" \
|
||||
-u "$READER:$READER_PASS" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "installer-readonly", "scopes": ["read:repository"]}'
|
||||
```
|
||||
Reference in New Issue
Block a user