Files
APAW/.kilo/shared/gitea-auth.md
¨NW¨ 7523911812 fix(security): extricate hardcoded Gitea credentials, add centralized auth module
- Remove all hardcoded NW:eshkink0t credentials from 9 files across skills, commands, rules, and specs
- Add .kilo/shared/gitea-auth.md with get_gitea_token() and .kilo/gitea.jsonc config structure
- All Gitea API callers now use env vars (GITEA_TOKEN → GITEA_USER+GITEA_PASS → ValueError)
- Fix task-analysis/SKILL.md broken functions (orphaned req references, stray parentheses)
- Replace hardcoded UniqueSoft/APAW API URLs with get_target_repo() auto-detection in 3 files
- Update README.md, STRUCTURE.md, AGENTS.md with centralized auth documentation
- Add EVOLUTION_LOG Entry #5 documenting credentials extrication
2026-04-19 11:43:59 +01:00

124 lines
4.0 KiB
Markdown

# Gitea Auth Module (Shared)
Centralized authentication for Gitea API. **NEVER hardcode credentials in agent code.**
## Auth Resolution Order
```
1. GITEA_TOKEN env var → Use directly (PREFERRED)
2. GITEA_USER + GITEA_PASS → Create temporary token via Basic Auth
3. .env file → Read env vars from .env
4. Interactive prompt → Ask user (last resort)
```
## Configuration
All credentials come from environment variables defined in `.kilo/gitea.jsonc`:
| Env Var | Required | Description |
|---------|----------|-------------|
| `GITEA_API_URL` | No | API base URL (default: `https://git.softuniq.eu/api/v1`) |
| `GITEA_TOKEN` | Preferred | Pre-existing API token |
| `GITEA_USER` | Fallback | Username for Basic Auth token creation |
| `GITEA_PASS` | Fallback | Password for Basic Auth token creation |
| `GITEA_TARGET_REPO` | No | Override target project (auto-detected otherwise) |
## Python Auth Function
```python
import os
import base64
import json
import urllib.request
def get_gitea_config():
"""Load Gitea configuration from env vars. NEVER hardcode credentials."""
return {
'api_url': os.environ.get('GITEA_API_URL', 'https://git.softuniq.eu/api/v1'),
'token': os.environ.get('GITEA_TOKEN', ''),
'user': os.environ.get('GITEA_USER', ''),
'pass': os.environ.get('GITEA_PASS', ''),
}
def get_gitea_token():
"""Get Gitea API token. Prefers GITEA_TOKEN env var.
Falls back to creating token via Basic Auth from GITEA_USER/GITEA_PASS.
Raises ValueError if no credentials available."""
config = get_gitea_config()
# 1. Use existing token (preferred)
if config['token']:
return config['token']
# 2. Create token via Basic Auth (fallback)
user = config['user']
password = config['pass'] # Note: 'pass' is reserved word, use config['pass']
if not user or not password:
raise ValueError(
'Gitea auth required. Set GITEA_TOKEN or GITEA_USER+GITEA_PASS env vars. '
'Create .env file with: GITEA_TOKEN=your-token'
)
credentials = base64.b64encode(f"{user}:{password}".encode()).decode()
req = urllib.request.Request(
f"{config['api_url']}/users/{user}/tokens",
data=json.dumps({"name": f"agent-{os.getpid()}", "scopes": ["all"]}).encode(),
headers={
'Content-Type': 'application/json',
'Authorization': f'Basic {credentials}',
},
method='POST',
)
with urllib.request.urlopen(req) as r:
return json.loads(r.read())['sha1']
```
## Bash Auth Function
```bash
# Get Gitea token — prefers GITEA_TOKEN, falls back to Basic Auth
get_gitea_token() {
if [ -n "$GITEA_TOKEN" ]; then
echo "$GITEA_TOKEN"
return
fi
if [ -z "$GITEA_USER" ] || [ -z "$GITEA_PASS" ]; then
echo "ERROR: Set GITEA_TOKEN or GITEA_USER+GITEA_PASS" >&2
return 1
fi
local API_URL="${GITEA_API_URL:-https://git.softuniq.eu/api/v1}"
local CRED=$(echo -n "$GITEA_USER:$GITEA_PASS" | base64)
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Basic $CRED" \
-d '{"name":"agent-token","scopes":["all"]}' \
"$API_URL/users/$GITEA_USER/tokens" | jq -r '.sha1 // empty'
}
```
## .env File Template
```bash
# Gitea Integration (NEVER commit this file)
GITEA_API_URL=https://git.softuniq.eu/api/v1
GITEA_TOKEN=your-api-token-here
# Fallback (only if no token):
# GITEA_USER=your-username
# GITEA_PASS=your-password
# GITEA_TARGET_REPO=Owner/RepoName
```
## CRITICAL RULES
1. **NEVER hardcode credentials** — no `username = "NW"` or `password = "eshkink0t"` in any file
2. **NEVER commit `.env`** — it's in `.gitignore`
3. **ALWAYS prefer `GITEA_TOKEN`** — tokens are scoped and revocable
4. **Fallback uses env vars**`GITEA_USER` + `GITEA_PASS`, not hardcoded strings
5. **Raise error if no creds** — don't silently fail, tell user to set env vars
6. **Use this module** — all Gitea API calls should use `get_gitea_token()` from here