Корпоративный справочник по текущей реализации аутентификации, авторизации и machine-access runtime в CodeGraph.
Область действия и источник истины¶
Документ описывает реализацию, которая сейчас находится в src/.
Канонические code surfaces:
| Область | Источник |
|---|---|
| Permission enum и role mapping | src/api/auth/tokens/permissions.py |
| Request auth context и FastAPI auth dependencies | src/api/auth/providers/middleware.py |
| JWT creation, validation и blacklist | src/api/auth/tokens/jwt_handler.py |
| User API-key helpers | src/api/auth/tokens/api_keys.py |
| Machine credential catalog и authorization | src/api/auth/machine/machine_access.py |
| Machine audit, project scope и optional mTLS binding | src/api/auth/machine/machine_runtime.py |
| API-key/service-account middleware | src/api/middleware/scope_enforcement.py |
| Path validation middleware | src/api/middleware/path_validation.py |
| Local, OAuth, LDAP, API-key, service-account routes | src/api/routers/auth_suite/* |
| User, API-key, tenant, project-access и service-account models | src/api/database/models_*.py |
Compatibility imports намеренно сохранены через src/api/auth/__init__.py: package path дополняется каталогами machine, providers и tokens. В новых ссылках лучше указывать физические пути из таблицы выше.
Runtime-модель¶
CodeGraph использует три связанных слоя авторизации:
| Слой | Что контролирует | Основная реализация |
|---|---|---|
| User RBAC | Ролевые разрешения human users для route dependencies и application logic | Permission, Role, ROLE_PERMISSIONS, has_permission() |
| Machine scopes | Доступ API keys и service accounts к API/MCP routes | MachinePrincipal, API_ROUTE_SCOPE_MAP, MCP_ROUTE_SCOPE_MAP, authorize_machine_request() |
| Tenant/project scope | Group membership и selected project access в multi-tenant инсталляциях | GroupRole, ProjectScopeMode, UserGroupAccess, UserProjectAccess, project repositories |
Методы аутентификации создают user identity или machine principal. Затем авторизация проверяет role permissions, raw scopes, interface allowlists, tenant/project restrictions и security middleware.
Пользовательские роли и разрешения¶
Роли¶
Роли пользователя определены в двух enum для разных границ:
| Enum | Источник | Назначение |
|---|---|---|
Role |
src/api/auth/tokens/permissions.py |
Permission checks в auth dependencies |
UserRole |
src/api/database/models_base.py |
Persisted user role в application DB |
Оба enum сейчас используют одинаковые значения:
| Роль | Value | Смысл |
|---|---|---|
VIEWER |
viewer |
Read-only product access |
ANALYST |
analyst |
Viewer плюс query/scenario execution, session writes, API-key creation, базовая работа с digital-employee tasks |
REVIEWER |
reviewer |
Analyst плюс review integrations и higher-risk digital-employee operations |
ADMIN |
admin |
Platform admin role |
src/api/dependencies.py::require_role() трактует роли как иерархию: viewer < analyst < reviewer < admin.
Поведение permission checks¶
Permission сейчас содержит 31 значение, включая admin:all.
Важные runtime-детали:
ROLE_PERMISSIONS[Role.ADMIN]хранит только{Permission.ADMIN_ALL}.get_role_permissions(Role.ADMIN)возвращает этот raw set; он не разворачивает его во все permissions.has_permission(Role.ADMIN, ...)возвращаетTrueдля любого запрошенного permission.- Explicit scopes также дают доступ, если строка scope совпадает с
Permission.value. - Scope
admin:allдает все permission checks вhas_permission()и обходит machine scope checks.
Каталог permissions¶
| Permission | Enum name | Viewer | Analyst | Reviewer | Admin |
|---|---|---|---|---|---|
scenarios:read |
SCENARIOS_READ |
x | x | x | x |
scenarios:execute |
SCENARIOS_EXECUTE |
x | x | x | |
query:execute |
QUERY_EXECUTE |
x | x | x | |
query:validate |
QUERY_VALIDATE |
x | x | x | |
review:execute |
REVIEW_EXECUTE |
x | x | ||
review:github |
REVIEW_GITHUB |
x | x | ||
review:gitlab |
REVIEW_GITLAB |
x | x | ||
sessions:read |
SESSIONS_READ |
x | x | x | x |
sessions:write |
SESSIONS_WRITE |
x | x | x | |
sessions:delete |
SESSIONS_DELETE |
x | x | x | |
history:read |
HISTORY_READ |
x | x | x | x |
history:export |
HISTORY_EXPORT |
x | x | x | |
users:read |
USERS_READ |
x | |||
users:write |
USERS_WRITE |
x | |||
users:delete |
USERS_DELETE |
x | |||
api_keys:read |
API_KEYS_READ |
x | x | x | |
api_keys:write |
API_KEYS_WRITE |
x | x | x | |
api_keys:delete |
API_KEYS_DELETE |
x | |||
stats:read |
STATS_READ |
x | x | x | x |
metrics:read |
METRICS_READ |
x | |||
digital_employees:read |
DIGITAL_EMPLOYEES_READ |
x | x | x | |
digital_employees:task:write |
DIGITAL_EMPLOYEES_TASK_WRITE |
x | x | x | |
digital_employees:task:high_risk |
DIGITAL_EMPLOYEES_HIGH_RISK_TASK |
x | x | ||
digital_employees:handoff:write |
DIGITAL_EMPLOYEES_HANDOFF_WRITE |
x | x | ||
digital_employees:approval:write |
DIGITAL_EMPLOYEES_APPROVAL_WRITE |
x | x | ||
digital_employees:audit:write |
DIGITAL_EMPLOYEES_AUDIT_WRITE |
x | x | ||
digital_employees:external_publish:write |
DIGITAL_EMPLOYEES_EXTERNAL_PUBLISH |
x | x | ||
digital_employees:lifecycle:write |
DIGITAL_EMPLOYEES_LIFECYCLE_WRITE |
x | |||
digital_employees:control_tower:repair |
DIGITAL_EMPLOYEES_CONTROL_TOWER_REPAIR |
x | |||
digital_employees:admin |
DIGITAL_EMPLOYEES_ADMIN |
x | |||
admin:all |
ADMIN_ALL |
x |
ROLE_PERMISSIONS сейчас не включает USERS_*, API_KEYS_DELETE, METRICS_READ, admin-only digital-employee permissions и ADMIN_ALL для не-admin ролей. На практике они доступны через Role.ADMIN или explicit scope admin:all.
Permission helpers¶
Для role/scope checks используйте src.api.auth.permissions:
from src.api.auth.permissions import (
Permission,
Role,
get_default_scopes_for_api_key,
get_role_permissions,
has_all_permissions,
has_any_permission,
has_permission,
validate_scopes,
)
Ключевое поведение:
get_default_scopes_for_api_key()возвращаетscenarios:read,scenarios:execute,query:execute,sessions:read,sessions:write,history:read.validate_scopes()фильтрует неизвестные строки поPermissionenum.has_permission()сначала учитывает role grants, затем explicit scope strings.
FastAPI Auth Context¶
AuthContext определен в src/api/auth/providers/middleware.py.
Поля:
| Поле | Смысл |
|---|---|
user_id |
Human user id, если есть |
subject_id |
Канонический subject id: user id или service-account id |
subject_type |
user или service_account |
username |
Display name или username |
role |
Optional Role для user RBAC |
scopes |
Raw permission/scope strings |
auth_method |
jwt, api_key, service_account_api_key, iam, local_plugin или none |
group_id |
Optional tenant/group scope |
project_id |
Optional project scope для service accounts |
service_account_id |
Service-account id при machine auth |
credential_id |
API key или service-account credential id |
allowed_interfaces |
Interfaces, разрешенные для authenticated subject |
Основной dependency flow:
- Повторно использовать
request.state.machine_principal, еслиScopeEnforcementMiddlewareуже проверил API key. - Проверить
X-YC-IAM-Token, если IAM включен. - Проверить JWT bearer token и отклонить blacklisted JWT ids.
- Проверить
X-API-Keyкак machine credential. - Вернуть unauthenticated context, если валидных credentials нет.
Route code должен использовать эти dependencies:
from src.api.auth.middleware import (
get_auth_context,
get_current_user,
get_optional_user,
require_admin,
require_analyst,
require_any_permission,
require_auth,
require_auth_or_localhost,
require_permission,
require_reviewer,
require_role,
)
require_auth_or_localhost() разрешает local plugin traffic только при security.local_dev_unauthenticated_surfaces_enabled=true и loopback-запросе. Mutating local-plugin requests должны содержать X-Actor-Agent-Id и X-Task-Id; generic agent ids вроде codex или codex-headless отклоняются.
src/api/dependencies.py также содержит database-backed dependencies, которые возвращают ORM User. Auth-suite routes используют их для account administration и API-key CRUD.
Методы аутентификации¶
Local username/password¶
Routes монтируются под /api/v1/auth:
| Route | Назначение |
|---|---|
POST /register |
Создать local user и вернуть tokens |
POST /login |
Login alias для token issuance |
POST /token |
Основной username/password token endpoint |
POST /refresh |
Rotate refresh token и выдать новые tokens |
DELETE /logout |
Добавить текущий bearer token в blacklist |
POST /oauth/token |
RFC 6749-compatible password и refresh-token grants |
Local passwords хешируются через bcrypt. Новые self-registered users получают роль analyst.
JWT Bearer Tokens¶
JWT code находится в src/api/auth/tokens/jwt_handler.py.
Поля TokenPayload:
| Поле | Смысл |
|---|---|
sub |
Subject user id |
jti |
JWT id |
exp |
Expiration |
iat |
Issued-at time |
type |
access или refresh |
scopes |
Raw permission scope strings |
role |
Optional user role string |
group_id |
Optional group scope |
Defaults:
- Access token TTL: 30 минут, если
expires_deltaне передан. - Refresh token TTL: 7 дней.
- Signing settings берутся из
src/api/config.py(API_JWT_ALGORITHM, JWT secret resolution).
Revocation:
blacklist_token()сохраняет SHA-256 fingerprint от JTI в memory и в таблицуtoken_blacklist.is_token_blacklisted()проверяет memory first, затем database.load_blacklist_cache()загружает неистекшие blacklist rows при startup._blacklist_sync_task()периодически обновляет in-memory cache.
User API keys¶
User API keys создаются через /api/v1/me/api-keys и передаются как X-API-Key.
Формат:
rag_<8 hex chars>_<48 hex chars>
Детали реализации:
generate_api_key()возвращает(full_key, prefix, key_hash).- Prefix начинается с
rag_. - Secret генерируется через
secrets.token_hex(24). - Stored hash: SHA-256.
verify_api_key()используетsecrets.compare_digest().ApiKey.group_idможет ограничить ключ одним tenant group.- User API keys аутентифицируются как
MachinePrincipal(subject_type="user", auth_method="api_key"). - User API keys по умолчанию разрешают interfaces
apiиmcp. ApiKeyInfo— response model без секрета.ApiKeyWithSecretрасширяетApiKeyInfoи возвращается только при создании ключа.
API-key CRUD:
| Route | Назначение |
|---|---|
POST /api/v1/me/api-keys |
Создать key для текущего пользователя |
GET /api/v1/me/api-keys |
Список keys текущего пользователя без secrets |
DELETE /api/v1/me/api-keys/{key_id} |
Revoke owned key |
Create request по умолчанию использует ["scenarios:read", "query:execute"]; lower-level helper get_default_scopes_for_api_key() возвращает более широкий legacy default list. Route behavior является авторитетным runtime behavior.
Service accounts¶
Service accounts используют тот же транспорт X-API-Key, но другой credential prefix:
svc_<8 hex chars>_<48 hex chars>
Service-account records хранятся в service_accounts; credentials хранятся в service_account_credentials.
Реализованные controls:
- Admin-only service-account management.
- Policy templates:
ci,portal,bot,agent. - Explicit
scopesиallowed_interfaces. - Optional
group_idилиproject_idrestriction. - Account expiry и credential expiry.
- Credential rotation без немедленного revoke старого credential.
- Active credential quota через
security.service_account_max_active_credentials. - Revoke и deactivate flows.
- Machine contract header:
X-CodeGraph-Machine-Contract, сейчас2026-03-v1. - Optional proxy-terminated mTLS binding для configured interfaces.
- Unified machine audit events через
AuditAction.MACHINE_ACCESS.
Admin routes:
| Route | Назначение |
|---|---|
GET /api/v1/admin/identity/service-accounts/action-catalog |
Вернуть route scopes, machine contract, policy templates и security limits |
POST /api/v1/admin/identity/service-accounts |
Создать service account и initial credential |
GET /api/v1/admin/identity/service-accounts |
Список service accounts |
GET /api/v1/admin/identity/service-accounts/{service_account_id} |
Inspect service account и credential metadata |
POST /api/v1/admin/identity/service-accounts/{service_account_id}/rotate |
Выдать новый credential |
POST /api/v1/admin/identity/service-accounts/{service_account_id}/credentials/{credential_id}/revoke |
Revoke один credential |
POST /api/v1/admin/identity/service-accounts/{service_account_id}/deactivate |
Disable account и revoke credentials |
Policy templates:
| Template | Scopes | Interfaces |
|---|---|---|
ci |
query:execute, scenarios:read, mcp:access |
api, mcp |
portal |
stats:read, history:read |
api |
bot |
query:execute, scenarios:read, mcp:access |
api, mcp |
agent |
query:execute, scenarios:execute, review:execute, mcp:access, digital_employees:read, digital_employees:task:write |
api, mcp |
OAuth2/OIDC¶
OAuth code находится в src/api/auth/providers/oauth.py; routes находятся в auth_external_routes.py.
Поддерживаемые provider implementations:
| Provider | Notes |
|---|---|
github |
GitHub OAuth |
gitlab |
GitLab OAuth, configurable server URL |
google |
Google OIDC |
keycloak |
Keycloak OIDC, configurable server and realm |
sourcecraft |
SourceCraft provider на базе Yandex ID |
gitverse |
GitVerse provider |
Routes:
| Route | Назначение |
|---|---|
GET /api/v1/auth/oauth/providers |
Список configured providers и generated authorize URLs |
GET /api/v1/auth/oauth/{provider} |
Start OAuth flow |
GET /api/v1/auth/oauth/{provider}/callback |
Exchange code, create/find user, issue JWTs |
Configured OAuth users получают JWTs с persisted database role.
LDAP/Active Directory¶
LDAP code находится в src/api/auth/providers/ldap_auth.py; route integration есть в auth_external_routes.py.
Routes:
| Route | Назначение |
|---|---|
POST /api/v1/auth/ldap |
Authenticate against LDAP/AD и issue JWTs |
GET /api/v1/auth/ldap/status |
Report LDAP availability и connection status |
Runtime caveat: LDAPAuthenticator.map_groups_to_role() читает config.group_role_mapping. Убедитесь, что deployed LDAPConfig предоставляет этот attribute, иначе все LDAP-created users откатятся к роли analyst.
Yandex Cloud IAM¶
IAM validation находится в src/api/auth/providers/iam.py и инициализируется из API settings, когда IAM включен.
Request header:
X-YC-IAM-Token: <token>
Когда token валиден, get_auth_context() возвращает:
role=Role.ANALYSTscopes=["scenarios:read", "query:execute", "review:execute"]auth_method="iam"
Validation results кешируются на configured IAM token cache TTL.
Machine scope enforcement¶
ScopeEnforcementMiddleware добавляется в src/api/main.py, когда security.api_key_scope_enforcement=true. Он проверяет requests с X-API-Key до выполнения router.
Процесс:
- Validate key как user API key или service-account credential.
- Сохранить
MachinePrincipalвrequest.state.machine_principal. - Resolve requested project scope из
X-Project-Id. - Validate optional machine contract header.
- Validate optional mTLS binding для service accounts.
- Выполнить
authorize_machine_request(). - Записать machine audit event.
- Вернуть
403 insufficient_scopeпри denial.
Выдержка из API route scope map:
| Prefix | Required scope |
|---|---|
/scenarios |
scenarios:read |
/query |
query:execute |
/review |
review:execute |
/sessions |
sessions:read |
/history |
history:read |
/stats |
stats:read |
/metrics |
metrics:read |
/security, /import, /documentation, /edit, /optimize, /standards, /composition, /changelog, /acp, /chat |
scenarios:execute |
/gocpg, /context, /patterns |
query:execute |
/deps |
scenarios:read |
/dashboard |
stats:read |
/digital-employees |
digital_employees:read |
/groups, /projects |
admin:all |
/webhooks, /health, /auth, /demo, /ws |
public для middleware scope purposes |
MCP route scope map:
| Prefix | Required scope |
|---|---|
/mcp |
mcp:access |
/sse |
mcp:access |
/messages |
mcp:access |
Только для MCP scope mcp:access может быть удовлетворен aliases: query:execute, scenarios:read, scenarios:execute, review:execute, stats:read, history:read и admin:all.
Explicit endpoint scope checks:
from src.api.auth.tokens.scope_enforcement import require_scope
@router.get("/example")
async def example(auth=Depends(require_scope("query:execute"))):
...
require_scope() проверяет raw AuthContext.scopes; admin:all обходит эту проверку.
Tenant и project access¶
Tenant/project authorization отделена от глобальных user roles.
Enums и tables:
| Surface | Values или назначение |
|---|---|
GroupRole |
viewer, editor, admin |
ProjectScopeMode |
all, selected |
project_groups |
Tenant/group records |
user_group_access |
User membership и tenant role |
user_project_access |
Selected project allowlist при membership mode selected |
api_keys.group_id |
Optional tenant restriction для user API keys |
service_accounts.group_id / project_id |
Optional tenant/project restriction для service accounts |
Admin access-management routes:
| Route | Назначение |
|---|---|
GET /api/v1/admin/identity/users/{user_id}/access |
Прочитать unified system role плюс tenant/project assignments |
PUT /api/v1/admin/identity/users/{user_id}/access |
Replace system role и tenant/project assignments |
Guardrails:
- Platform admin не может deactivate свой собственный account.
- Last active platform admin не может быть deactivated или downgraded.
- Last tenant admin не может быть removed или downgraded без другого tenant admin.
selectedproject scope должен включать хотя бы один project, и все selected projects должны принадлежать assigned tenant.allproject scope не может включать explicit project ids.
Project resolution и tenant-sensitive runtime paths должны использовать ProjectContext и resolved project scope, а не user-provided database paths.
Path Validation Middleware¶
PathValidationMiddleware проверяет поля db_path и source_path в JSON bodies для POST, PUT и PATCH.
Правила:
- Empty strings и NUL bytes отклоняются.
- Relative paths отклоняются, если
path_validation_deny_relative=true. - Path components
..отклоняются. - Paths resolve-ятся через
os.path.realpath(). - Resolved path должен находиться под allowed base directory.
Allowed directories строятся из:
security.path_validation_allowed_base_dirs- parent directories зарегистрированных project
db_path - зарегистрированных project
source_pathdirectories
Config fields определены в SecurityConfig:
| Field | Default |
|---|---|
path_validation_enabled |
true |
path_validation_deny_symlinks |
true |
path_validation_deny_relative |
true |
path_validation_allowed_base_dirs |
["data/projects/"] |
Webhook authentication¶
Webhook verification находится в src/api/auth/machine/webhook_auth.py.
Основная функция проверки — verify_webhook_signature().
Поддерживаемые platforms:
| Platform | Signature/token header | Timestamp header |
|---|---|---|
sourcecraft |
X-SourceCraft-Signature |
X-SourceCraft-Timestamp |
gitverse |
X-GitVerse-Signature; fallbacks включают X-Gitea-Signature, X-Gogs-Signature, X-Hub-Signature-256, X-Hub-Signature |
X-GitVerse-Timestamp |
github |
X-Hub-Signature-256 |
X-Hub-Timestamp |
gitlab |
X-Gitlab-Token |
none |
sourcecraft, gitverse и github используют HMAC signature validation. gitlab использует constant-time token comparison. Replay protection использует configured security.webhook_max_age_seconds, когда у platform есть timestamp header.
Audit и SIEM-relevant events¶
Audit actions определены в src/api/logging/audit_logger.py.
Authorization-related actions:
| Category | Actions |
|---|---|
| Auth | auth.login.success, auth.login.failure, auth.logout, auth.token.refresh, auth.token.revoked |
| OAuth and LDAP | oauth.login.*, ldap.login.* |
| API keys | api_key.created, api_key.revoked, api_key.deleted, api_key.used |
| Service accounts | service_account.created, service_account.rotated, service_account.credential_revoked, service_account.disabled |
| Machine access | machine.access |
| User and tenant admin | user.created, user.updated, user.role.changed, user.tenant.*, user.project.scope.changed |
| Security | security.permission.denied, security.rate_limit.exceeded, security.token.invalid, security.path_violation, security.idor_attempt, security.webhook.replay_rejected, security.mcp.auth_failure |
Machine audit records содержат subject type/id, interface, operation, resource, result, credential id, optional service-account id, optional contract version, project id и group id.
Configuration reference¶
Selected current config fields:
| Field | Назначение |
|---|---|
security.api_key_scope_enforcement |
Включает machine API-key scope middleware |
security.local_dev_unauthenticated_surfaces_enabled |
Включает guarded loopback local-plugin auth bypass |
security.webhook_max_age_seconds |
Replay window для timestamped webhook signatures |
security.auth_rate_limit_* |
Login/register/refresh/LDAP rate-limit settings |
security.service_account_token_ttl_days |
Default service-account account и credential TTL |
security.service_account_default_interfaces |
Default interfaces для service accounts |
security.service_account_max_active_credentials |
Rotation quota |
security.service_account_rotation_overlap_seconds |
Intended overlap window для rotations |
security.service_account_rotation_warning_days |
Warning window для credential age/expiry |
security.service_account_revoke_sla_seconds |
Revocation SLA reference |
security.service_account_mtls_enabled |
Включает service-account mTLS binding checks |
security.service_account_mtls_required_interfaces |
Interfaces, требующие mTLS при включенной проверке |
security.service_account_mtls_subject_header |
Proxy header для certificate subject |
security.service_account_mtls_fingerprint_header |
Proxy header для certificate fingerprint |
security.service_account_mtls_bindings |
Allowed fingerprints by service-account id |
Операционные рекомендации¶
Для администраторов:
- Используйте
adminтолько для platform administration. - Для повседневной сегрегации предпочитайте tenant
GroupRoleи selected project access. - Используйте service accounts для CI, bots, portals, MCP clients и long-lived machine access.
- Берите policy templates как baseline и добавляйте только нужные caller scopes.
- Rotate service-account credentials до revoke старых credentials.
- Оставляйте JWT blacklist cache loading включенным при application startup.
- Держите path validation и API-key scope enforcement включенными в shared environments.
Для разработчиков:
- Используйте
require_permission()илиrequire_role()для human user route checks. - Используйте
require_scope()только когда raw scope strings являются intended contract. - Добавляйте новые machine routes в
API_ROUTE_SCOPE_MAPилиMCP_ROUTE_SCOPE_MAP. - Сохраняйте REST/MCP parity через shared services, а не дублирование auth logic.
- Никогда не авторизуйте tenant-sensitive operations от user-provided
db_path. - Для mutating local-plugin routes требуйте named actor и task evidence.
- Не логируйте bearer tokens, API keys, service-account secrets, raw webhook secrets или raw prompts.
Связанные документы¶
- Обзор корпоративной безопасности
- OAuth2/OIDC и LDAP/AD Integration
- SIEM Integration
- DLP Security
- REST API Reference
Версия: 3.0 | Май 2026