API 문서
Alpacon은 서버의 상태를 제어하고 관리할 수 있는 RESTful API를 제공합니다. API의 루트 경로는 /api/입니다.
API 엔드포인트
각 워크스페이스는 전용 API 엔드포인트를 갖습니다:
https://<workspace>.<region>.alpacon.io/api/여기서:
<workspace>: 워크스페이스 슬러그<region>: 워크스페이스 리전 (생성 시 할당)
예시: https://mycompany.ap1.alpacon.io
개인 설정에서 워크스페이스 엔드포인트 URL 전체를 확인할 수 있습니다.
이 문서의 모든 API 예시는 https://your-workspace.ap1.alpacon.io를 예시 주소로 사용합니다. 실제 워크스페이스 엔드포인트로 대체하세요.
인증
토큰은 Authorization 헤더에 담아 보냅니다. 두 종류의 토큰 모두 형식이 같습니다.
Authorization: token="alpst-xxxxxxxxxxxxxxxxxx"| 토큰 | 접두사 | 용도 |
|---|---|---|
| 서비스 토큰 | alpst- | 자동화. 명령 실행과 파일 전송은 서비스 토큰의 접근 제어 규칙 안에서 이뤄집니다. 애플리케이션에 발급합니다. |
| 개인 API 토큰 | alpat- | 본인 권한으로 API에 접근해, 토큰의 scope와 현재 역할 안에서 리소스를 조회하고 관리합니다. API 토큰에서 만듭니다. |
- 키워드는 소문자
token이며, 그 뒤에=와 키를 붙입니다. 따옴표는 생략해도 되므로token=alpst-...도 동작합니다.Authorization: Bearer alpst-...형식은 두 토큰 모두 받지 않습니다. - 명령은 작업 세션 안에서, 또는 서비스 토큰으로 실행합니다.
- 명령 실행과 파일 전송을 자동화할 때는 서비스 토큰을 사용하세요.
- 개인 API 토큰을 관리하려면 토큰이 아니라 로그인한 세션이 필요합니다. API 토큰을 참고하세요.
일부 관리 API를 호출하려면 로그인 세션이 필요합니다. 세션 전용으로 표시된 경로는 alpat-와 alpst- 키를 받지 않습니다. 서비스 토큰으로 자동화하기를 따라 CLI와 웹 콘솔에서 설정하세요. CLI에서 생성한 서비스 토큰은 항상 웹 콘솔에서 승인을 기다립니다. API별로 허용하는 인증 방식은 각 페이지를 확인하세요.
자격 증명이 거부되면 401과 함께 다음 코드 중 하나가 돌아옵니다.
| 코드 | 상황 |
|---|---|
auth_token_missing | 자격 증명이 없거나, 개인 API 토큰이 존재하지 않거나 비활성화·만료되었거나, 토큰 사용자가 비활성 상태임 |
auth_authentication_failed | 서비스 토큰이 없거나 비활성화·승인 대기·만료 상태이거나, 소속 애플리케이션이 삭제됨 |
auth_ip_not_allowed | 서비스 토큰을 허용 IP 대역 밖에서 사용함 |
auth_access_outside_allowed_time | 서비스 토큰을 허용된 요일·시간 밖에서 사용함 |
auth_mfa_required | 최근 MFA 확인이 필요한 작업임. 401 본문의 source에 어떤 확인인지 표시됨 |
auth_token_mfa_missing | 콘솔, CLI, MCP에서 로그인할 때 워크스페이스가 요구하는 MFA를 마치지 않았거나, 워크스페이스가 허용하지 않는 MFA 방법으로 마친 뒤 받은 토큰임. 로그인한 뒤 MFA가 켜진 경우가 대표적임. 토큰을 갱신해도 해결되지 않으므로 다시 로그인해서 MFA를 마쳐야 함(CLI는 alpacon login) |
auth_client_instance_revoked | 철회된 로그인에서 받은 토큰임. 다시 로그인해야 함 |
작업 세션 경로와 승인 API 모두 승인·거절 시 최근 MFA 확인이 없으면 source 없이 400 auth_mfa_required가 돌아옵니다. 작업 세션을 참고하세요.
그 순간 Alpacon이 자격 증명을 확인할 수 없으면 503과 auth_verification_unavailable이 돌아옵니다. 자격 증명이 거부된 것은 아니므로 요청을 다시 보내면 됩니다.
전역 정보
HTTP 메서드
| 메서드 | 용도 |
|---|---|
GET | 리소스 목록 조회 또는 단일 조회 |
POST | 리소스 생성 |
PUT | 리소스 전체 교체 |
PATCH | 리소스의 특정 필드 수정 |
DELETE | 리소스 삭제 |
자세한 내용은 MDN HTTP 메서드 레퍼런스를 참조하세요.
URL 구조
API는 다음과 같은 URL 구조를 따릅니다:
- 목록 조회 또는 생성:
/api/<collection>/<resource>/ - 단일 조회, 수정, 삭제:
/api/<collection>/<resource>/<id>/ - 추가 액션:
/api/<collection>/<resource>/<id>/<action>/
예를 들어, GET /api/iam/users/a540bf0f-8b37-4f03-8546-dd71c6b03329/는 해당 사용자의 상태를 조회합니다.
※ 모든 API URL은 슬래시(/)로 끝납니다.
페이지 나누기
대부분의 목록 API는 한 번에 한 페이지씩 돌려줍니다. 작업 세션의 타임라인과 기록은 커서로 페이지를 나누며 응답 형식과 한도도 다릅니다.
페이지 번호를 사용하는 API의 형식은 다음과 같습니다.
| 매개변수 | 의미 |
|---|---|
page | 페이지 번호. 1부터 시작 |
page_size | 페이지당 결과 수. 기본값 15, 최대 100이며 더 큰 값은 100으로 처리 |
{
"count": 85,
"current": 1,
"next": 2,
"previous": null,
"last": 6,
"results": []
}count는 전체 결과 수, current는 현재 페이지, last는 마지막 페이지입니다. next와 previous는 URL이 아니라 페이지 번호이며, 처음이나 끝에서는 null입니다. 결과를 모두 읽으려면 next가 null이 될 때까지 page=next로 요청하세요. last보다 큰 페이지를 요청하면 404와 api_not_found가 돌아옵니다.
상태 코드
성공 코드:
| 코드 | 의미 | 일반적인 메서드 |
|---|---|---|
200 OK | 요청 성공 | GET, PUT, PATCH |
201 Created | 리소스 생성됨 | POST |
202 Accepted | 승인 또는 비동기 처리를 위해 요청이 접수됨. 응답에 대기 중인 내용이 담김. 예를 들어 토큰 scope 변경에 승인이 필요할 수 있음 | PATCH, PUT, POST |
204 No Content | 리소스 삭제됨 | DELETE |
승인이 필요한 요청이 항상 202를 반환하는 것은 아닙니다. 작업 세션 생성은 승인이 필요해도 201과 status: "pending"을 반환합니다. 세션을 주기적으로 조회해 처리 결과를 확인하세요.
오류 코드:
| 코드 | 의미 |
|---|---|
400 Bad Request | 잘못된 요청 데이터. 필드별 상세 내용은 에러 메시지를 참조하세요. |
401 Unauthorized | 인증되지 않음. 코드는 인증을 참조하세요. |
402 Payment Required | 워크스페이스 플랜, 또는 활성화하지 않은 워크스페이스 확장 기능이 이 작업을 지원하지 않습니다. 거부 응답을 참조하세요. |
403 Forbidden | 권한 없음. 자격 증명은 유효하지만 이 작업은 할 수 없습니다. 응답 본문은 코드가 포함된 거부 응답입니다. |
404 Not Found | 리소스가 없거나, 이 자격 증명으로는 볼 수 없음. 코드는 api_not_found입니다. |
405 Method Not Allowed | 이 엔드포인트에서 지원하지 않는 HTTP 메서드. |
409 Conflict | 요청은 올바르지만 리소스의 현재 상태 때문에 처리할 수 없음. 나중에 다시 시도하면 성공할 수 있습니다. |
429 Too Many Requests | 요청 빈도 제한에 걸림. Retry-After 헤더가 포함됩니다. 요청 한도를 참조하세요. |
503 Service Unavailable | 연동된 구성 요소가 응답하지 못함. 자격 증명 확인 중이면 auth_verification_unavailable, 세션 기록 조회 중이면 api_search_unavailable입니다. 요청을 다시 보내세요. |
500 Server Error | 서버 내부 오류. |
HTTP 상태 코드의 전체 목록은 MDN HTTP 상태 코드 레퍼런스를 참조하세요.
에러 메시지
모든 오류 응답에는 기계가 읽을 수 있는 code가 포함됩니다. 예외는 엔드포인트가 지원하지 않는 메서드에 대한 405 하나로, 이 경우 {"detail": "..."}가 돌아옵니다. 400 Bad Request에는 문제를 특정 필드에 연결할 수 있는 경우 field_errors가 추가로 포함되며, 특정 필드에 속하지 않는 오류는 field_errors 안의 non_field_errors 키로 표시됩니다.
예를 들어 사용자의 비밀번호를 변경할 때 새 비밀번호가 서버 측 검증을 통과하지 못하면 아래와 같은 응답을 받게 됩니다. 필드 이름(new_password)이 field_errors 안의 키로 사용됩니다. 연동은 message가 아니라 code를 기준으로 만드세요. message는 “Invalid input.”처럼 범용적인 문자열인 경우가 많고, 항상 영어로 고정되어 있지도 않습니다.
HTTP 400 Bad Request
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept{
"code": "password_too_short",
"field_errors": {
"new_password": [
{
"code": "password_too_short",
"message": "Invalid input."
}
]
}
}field_errors는 각 필드를 {code, message} 항목의 목록에 매핑합니다. 한 필드에서 여러 검증이 동시에 실패하면 항목이 여러 개 담길 수 있습니다.
특정 필드 하나에 속하지 않는 오류(예: 요청의 여러 값을 함께 보는 객체 수준 규칙)는 필드 이름 대신 field_errors 안의 non_field_errors 키로 표시됩니다.
{
"code": "approval_superuser_approve_required",
"field_errors": {
"non_field_errors": [
{
"code": "approval_superuser_approve_required",
"message": "Invalid input."
}
]
}
}400 응답이 모두 field_errors를 포함하는 것은 아닙니다. 특정 필드 없이 발생하는 검증 실패(예: 그룹에 남은 마지막 소유자를 삭제하려는 경우)는 최상위 code만 포함합니다.
{
"code": "user_unique_group_owner"
}어느 엔드포인트에서나 나올 수 있는 코드도 있습니다.
| 상태 | 코드 | 상황 |
|---|---|---|
| 400 | api_invalid_data | 요청 본문을 해석할 수 없음. JSON 형식이 잘못된 경우가 대표적이며, 일부 엔드포인트는 받을 수 없는 데이터에도 씀 |
| 406 | api_not_acceptable | Accept 헤더가 요구한 형식으로 엔드포인트가 응답할 수 없음 |
| 415 | api_unsupported_media_type | 엔드포인트가 받지 않는 Content-Type임. 엔드포인트가 안내하는 형식으로 보내야 하며, 대개 application/json임 |
| 500 | api_unknown_error | 예상하지 못한 서버 오류. 대부분 500으로 돌아옴. 조회 요청은 다시 보내면 되지만, 명령 실행처럼 무언가를 바꾸는 요청은 반영되었는지 먼저 확인한 뒤 다시 보내야 함 |
Application 역할 검증 오류
Application 역할을 부여하거나 제거할 때 다음 오류는 400으로 반환됩니다. 콘솔 설정 순서는 Application에 알림 규칙 하나의 관리 권한 부여를 참고하세요.
| 코드 | 의미 | 조치 |
|---|---|---|
rbac_application_role_global_required | Application에 워크스페이스 전체 역할이 없어 규칙 범위 역할 부여가 거부됨 | 필요한 토큰 scope를 포함하는 워크스페이스 전체 역할을 먼저 부여한 뒤 다시 시도 |
rbac_application_rule_roles_remain | 규칙 범위 역할이 남아 있어 마지막 워크스페이스 전체 역할을 제거할 수 없음 | 규칙 범위 역할을 모두 제거한 뒤 워크스페이스 전체 역할 제거 |
요청 한도
서비스 토큰은 토큰별로 한도를 따로 정하지 않았다면 시간당 1,000건까지 요청할 수 있습니다. 관리자는 토큰마다 초·분·시간·일 단위 요청 수로 한도를 다르게 정할 수 있습니다. 개인 API 토큰과 로그인한 세션에는 공통 한도가 없지만, 일부 엔드포인트에는 자체 한도가 있습니다.
한도를 넘으면 429와 함께 기다릴 시간(초)을 담은 Retry-After 헤더가 돌아옵니다.
HTTP 429 Too Many Requests
Retry-After: 120{
"code": "api_rate_limited",
"gate": "rate"
}Retry-After만큼 기다린 뒤 다시 시도하세요. 파이프라인이 자주 한도에 걸린다면 재시도를 서두를 것이 아니라 토큰의 한도를 높여야 합니다.
거부 응답
Alpacon 서버 2.37.0부터 제공됩니다.
이미 code가 있는 402, 403, 405, 429 응답에는 요청이 거부된 이유를 설명하는 필드가 추가로
들어갈 수 있습니다:
gate: 요청을 거부한 제어의 종류missing: 있었다면 요청이 통과했을 전제 조건의 종류. 토큰 scope 거부의 경우에 한해, 자격 증명에 없는 정확한 scope 문자열이 들어갑니다.hint: 사람이 읽을 수 있는 최대 두 문장의 영어 안내문입니다. 직접 할 수 있는 일 또는 부족한 조건과 기존 요청의 상태를 확인할 수 있는 위치를 설명합니다.
gate와 missing은 선택 필드이며, 서버가 거부 시점에 기록한 경우에만 나타납니다. 없으면 알 수 없는
다른 필드와 마찬가지로 무시하세요. hint는 제어 문자가 없는 최대 256바이트 문자열입니다. 인증된
요청의 거부 코드와 gate에 해당하는 안내가 있을 때 포함될 수 있습니다. hint는
그대로 출력하고 파싱하지 마세요. 로직은 code, gate, missing을 기준으로 작성하세요. 각 코드의
hint 문구는 거부 코드에 인용되어 있습니다. 이 필드들은 401 응답에는 들어가지
않습니다. 401에는 code가 들어가며, 401 auth_mfa_required에는 필요한 MFA 검사를 가리키는
source도 들어갑니다. 작업 세션 경로와 approvals API에서 승인과 거절에는 모두 source 없이
400 auth_mfa_required가 쓰입니다.
gate 값:
| 값 | 의미 |
|---|---|
work_session | 요청이 활성 작업 세션의 scope를 벗어남 |
role | 호출자의 RBAC 역할이 이 권한을 부여하지 않음 |
token_scope | API 토큰 또는 서비스 토큰이 이 작업에 필요한 scope를 보유하지 않음 |
server_reach | 자격 증명의 서버 접근 제어 규칙이 이 서버를 포함하지 않음 |
command_acl | 이 자격 증명에 대해 명령어가 사전 승인되지 않음 |
file_acl | 이 자격 증명의 파일 접근 제어 규칙이 이 전송의 경로, 계정 및 전송 방향을 허용하지 않음 |
approval | 이 작업에는 아직 받지 못한 사람의 승인이 필요함 |
presence | 이 작업에는 최근에 확인된 MFA/단계별 인증이 필요함 |
risk | 위험 기반 실행 제어에 의해 거부됨 |
sudo | sudo 요청이 거부됨 |
plan | 워크스페이스 플랜 또는 확장 기능이 이 작업을 지원하지 않음 (402). 리소스 한도 때문에 거부된 경우의 axis 필드는 아래 플랜 한도에 따른 요청 거부 참고 |
rate | 시간 기반 요청 빈도 제한에 의해 거부됨 (429) |
missing 값:
| 값 | 의미 |
|---|---|
command_preapproval | 이 명령어에 대한 사전 승인이 있었다면 통과했을 것 |
file_preapproval | 이 경로, 계정 및 전송 방향을 허용하는 파일 접근 제어 규칙이 있었다면 통과했을 것 |
approval | 승인이 있었다면 통과했을 것 |
presence | 최근 확인된 인증이 있었다면 통과했을 것 |
work_session | 활성 작업 세션이 있었다면 통과했을 것 |
plan | 더 높은 플랜 등급이었다면 통과했을 것 |
role | 이 권한을 부여하는 역할이 있었다면 통과했을 것 |
approved_account | 작업 세션에서 승인된 계정으로 실행하고 있었다면 통과했을 것 |
other_approver | 요청자가 아닌 승인자의 승인이 있었다면 통과했을 것 |
allowed_agent | 워크스페이스의 승인 정책이 허용하는 에이전트를 사용하고 있었다면 통과했을 것 |
scope:<resource>:<action> | missing이 가질 수 있는 유일한 리터럴 형태입니다. scope: 뒤에 토큰에 없는 scope가 플랫폼의 resource:action 형식 그대로 붙습니다(예: scope:server:update는 server:update scope를 가리킴). scope: 접두사는 이 거부 응답에서만 붙는 것이고, 토큰이나 scope 카탈로그 등 다른 곳에서 보게 되는 실제 scope 이름은 그냥 server:update입니다. 문자열 하나일 수도 있고, 부족한 scope가 여러 개면 문자열 목록일 수도 있습니다. |
예시: 역할 거부
{
"code": "rbac_permission_required",
"gate": "role",
"missing": "role",
"hint": "Your roles do not allow this action; it needs a role that covers it."
}예시: 토큰 scope 부족
{
"code": "api_token_scope_missing",
"gate": "token_scope",
"missing": "scope:server:update"
}gate, missing, hint에는 규칙의 내용, 다른 사용자의 신원, 누락된 항목을 요청할 수 있는 경로가
들어가지 않습니다. gate와 missing은 제어와 전제 조건의 종류만 나타내며, hint는 무엇이 없고
자신의 접근 범위 안에서 무엇을 할 수 있는지만 알려줍니다. 이 응답 형식에서 알 수 없는 필드는 참고
정보로 보고 무시해도 됩니다.
플랜 한도에 따른 요청 거부
Alpacon 서버 2.39.0부터 제공됩니다.
기능이 플랜에 포함되지 않아서가 아니라 리소스 한도에 도달해서 요청이 거부된 402 응답에는 gate: "plan"과 함께 도달한 한도를 나타내는 axis도 포함됩니다.
axis 값 | 나타내는 한도 |
|---|---|
server | 등록된 서버 수 |
user | 초대 대기 중인 사람을 포함한 워크스페이스 멤버 수 |
application | 애플리케이션 수(자동화용 ID) |
websh | 현재 사용 기간의 Websh 세션 사용 시간 |
webftp | 현재 사용 기간의 WebFTP 전송량 |
websh-share | 현재 사용 기간에 다른 사용자와 Websh 세션을 공유한 시간 |
workspace | Free 워크스페이스 수(이미 Free 워크스페이스에 속한 상태에서 다른 워크스페이스 생성) |
server, user, application은 개수 한도입니다. 응답 본문에는 워크스페이스의 플랜과 한도를 조회하는 상대 API 경로인 next도 포함됩니다. 이 경로는 로그인한 콘솔 세션에서만 호출할 수 있고, 토큰 인증으로는 호출할 수 없습니다. 토큰으로 API를 호출한다면 next는 참고용으로만 보고 현재 사용량은 콘솔에서 확인하세요. 개수 한도에는 초기화 시점이 없습니다. 항목을 삭제하거나 플랜을 업그레이드하면 다시 추가할 수 있습니다.
websh, webftp, websh-share는 월간 한도입니다. 응답에는 next 대신 이번 사용 기간이 끝날 때까지 남은 초를 나타내는 Retry-After 헤더가 포함됩니다. 플랜에 Websh 공유 기능이 포함되어 있지 않으면 websh-share 거부 응답에는 기다릴 초기화 시점이 없으므로 Retry-After도 포함되지 않습니다. workspace는 워크스페이스 안의 한도가 아니라 계정에 적용되는 규칙(속할 수 있는 Free 워크스페이스는 1개)이므로 next와 Retry-After가 모두 포함되지 않습니다.
응답 본문에는 현재 사용량이나 한도의 숫자 값이 포함되지 않습니다. 이 값은 next가 가리키는 경로나 콘솔의 플랜 및 사용량 상세 정보에서 확인하세요.
예시: 개수 한도(server):
HTTP 402 Payment Required{
"code": "server_limit_exceeded",
"gate": "plan",
"axis": "server",
"next": "/api/workspaces/workspaces/<workspace_id>/entitlements/"
}예시: 월간 한도(websh):
HTTP 402 Payment Required
Retry-After: 864000864000은 설명을 위한 값(10일)이며, 실제 응답에는 사용 기간이 끝날 때까지 남은 초가 담깁니다.
{
"code": "websh_limit_exceeded",
"gate": "plan",
"axis": "websh"
}gate: "plan"이 포함되고 axis는 없는 402 응답은 기능 제한을 뜻합니다. 해당 플랜에서는 사용량과 관계없이 이 기능을 사용할 수 없으며, 기다리거나 항목을 삭제해도 해결되지 않습니다.
{
"code": "workspace_enterprise_plan_required",
"gate": "plan"
}거부 코드
아래 코드가 402, 403, 405, 429 응답에 실릴 때는 본문이 모두 거부 형식입니다.
상태 코드는 플랜 관련 거부가 402, 요청 한도 관련 거부가 429, workspace_put_info_disabled와
command_acl_moved가 405, 나머지가 403입니다. 일부 코드는 다른 상태 코드의 응답에도 실리며,
이때 본문에는 거부 필드와 hint가 없습니다. 이때 상태 코드는 auth_mfa_required의 경우 400과
401, api_not_for_alpacon, permission_denied와 user_no_permission의 경우 400,
workspace_unclaimed와 workspace_not_unclaimed의 경우 409입니다. 거부 응답에 gate와
missing이 포함되어 있으면 표의 의미 열에 그 값이 명시되어 있습니다.
“조치”의 각 항목은 해당 코드의 hint를 그대로 옮긴 문장으로 시작합니다. 한 코드가 여러 gate에서
거부될 수 있으면 server_reach 게이트처럼 게이트 라벨 뒤에 그 게이트의 hint가 이어집니다. 항목의
나머지 부분에는 변경해야 하는 위치에 대한 설명이 있습니다. sudo 명령어 거부 코드는
PAM 및 sudo 문제에 나와
있습니다.
작업별 접근 판단과 해결 방법은 관련 오류 코드를 참고하세요.
역할과 권한
| 코드 | 의미 | 조치 |
|---|---|---|
rbac_permission_required# | 현재 맡은 역할에 이 작업에 필요한 권한이 없습니다. gate: role, missing: role에 해당합니다. | Your roles do not allow this action; it needs a role that covers it. 현재 맡은 역할로는 이 작업을 수행할 수 없습니다. 해당 작업을 허용하는 역할이 필요합니다. |
rbac_object_permission_required# | 현재 맡은 역할로는 이 항목에 대해 해당 작업을 수행할 수 없습니다. gate: role, missing: role에 해당합니다. | Your roles do not allow this action on this item; it needs a role that covers it. 현재 맡은 역할로는 이 항목에 대해 해당 작업을 수행할 수 없습니다. 해당 항목의 작업을 허용하는 역할이 필요합니다. |
rbac_application_update_required# | 여러 애플리케이션을 대상으로 한 요청에 현재 맡은 역할로 변경할 수 없는 애플리케이션이 하나 이상 포함되어 있습니다. | Your roles do not allow updating at least one of these applications; it needs a role that covers each of them. 현재 맡은 역할로는 대상 애플리케이션 중 하나 이상을 변경할 수 없습니다. 모든 대상 애플리케이션을 변경할 수 있는 역할이 필요합니다. |
permission_denied# | 이 자격 증명으로는 해당 작업을 수행할 수 없습니다. ACL 경로에서는 모든 토큰 요청에도 이 코드를 반환합니다. | This account or credential does not have permission for this action. 현재 계정이나 자격 증명에는 이 작업을 수행할 권한이 없습니다. |
user_no_permission# | 현재 계정으로는 사용자에 대해 이 작업을 수행할 수 없습니다. | Your account does not have permission for this action. 현재 계정에는 이 작업을 수행할 권한이 없습니다. |
user_privileged_removal_forbidden# | 삭제하려는 계정에 플랫폼 역할이 부여되어 있으며, 현재 사용자에게는 해당 계정을 삭제하는 데 필요한 권한이 없습니다. | Removing an account that holds a platform role needs a permission your roles do not include. 플랫폼 역할이 부여된 계정을 삭제하려면 별도 권한이 필요하지만 현재 맡은 역할에는 이 권한이 없습니다. |
membership_group_owner_required# | 그룹의 최상위 역할이 있는 사용자만 이 멤버의 그룹 소속 정보를 변경할 수 있습니다. | Changing this membership needs the top role in the group. 이 멤버의 그룹 소속 정보를 변경하려면 그룹의 최상위 역할이 필요합니다. |
membership_privilege_required# | 현재 맡은 그룹 역할의 권한 수준으로는 이 멤버를 추가하거나 제거할 수 없습니다. | Your role in this group is not high enough to add or remove this membership. 현재 맡은 그룹 역할의 권한 수준으로는 이 멤버를 추가하거나 제거할 수 없습니다. |
workspace_ai_corpus_owner_required# | 워크스페이스의 최상위 역할이 있는 사용자만 이 AI 설정을 변경할 수 있습니다. gate: role, missing: role에 해당합니다. | Your role cannot change this setting; it needs the workspace's highest role. 현재 맡은 역할로는 이 설정을 변경할 수 없습니다. 워크스페이스의 최상위 역할이 필요합니다. |
access_rules_admin_only# | 접근 규칙을 읽거나 이 유형의 평가를 실행하려면 더 높은 역할이 필요합니다. | Your role cannot read the access rules or run this kind of evaluation; it needs a role that covers it. 현재 맡은 역할로는 접근 규칙을 읽거나 이 유형의 평가를 실행할 수 없습니다. 해당 작업을 허용하는 역할이 필요합니다. |
metrics_alert_rule_core_admin_only# | 핵심 디스크 사용량 규칙과 그 규칙을 서버별로 덮어쓴 설정을 변경하려면 더 높은 역할이 필요합니다. | Your role cannot change the core disk rule or its per-server overrides; it needs a role that covers it. 현재 맡은 역할로는 핵심 디스크 사용량 규칙이나 그 규칙을 서버별로 덮어쓴 설정을 변경할 수 없습니다. 해당 작업을 허용하는 역할이 필요합니다. |
package_delete_not_allowed# | 패키지를 지우면 그 안의 파일도 함께 지워지는데, 현재 맡은 역할로는 그 파일을 모두 지울 수 없습니다. gate: role, missing: role에 해당합니다. | Deleting this package also deletes its entries, and your roles do not allow deleting them; it needs a role that covers it. 패키지를 지우면 안에 있는 파일도 함께 지워지는데, 현재 맡은 역할로는 그 파일을 지울 수 없습니다. 파일 삭제까지 허용하는 역할이 필요합니다. |
service_token_application_forbidden# | 현재 맡은 역할로는 이 애플리케이션의 서비스 토큰을 발급하거나 변경할 수 없습니다. | Your roles do not allow issuing or changing service tokens for this application. 현재 맡은 역할로는 이 애플리케이션의 서비스 토큰을 발급하거나 변경할 수 없습니다. |
service_token_break_glass_unauthorized# | 서비스 토큰의 break-glass scope를 활성화하려면 워크스페이스의 최상위 역할이 필요합니다. | Turning on break-glass access needs the workspace's highest role. break-glass를 활성화하려면 워크스페이스의 최상위 역할이 필요합니다. |
group_agent_approval_policy_authority_required# | 어느 그룹에 에이전트 승인이 필요한지는 승인 정책의 일부이며, 현재 맡은 역할로는 이를 변경할 수 없습니다. | Changing which group needs agent approval is an approval policy change, which your role does not allow. 어느 그룹에 에이전트 승인이 필요한지 변경하는 것은 승인 정책을 변경하는 작업입니다. 현재 맡은 역할로는 이 작업을 수행할 수 없습니다. |
workspace_execution_control_mode_superuser_required# | 워크스페이스의 최상위 역할이 있는 사용자만 실행 제어 모드를 변경할 수 있습니다. | Changing the execution control mode needs the workspace's highest role. 실행 제어 모드를 변경하려면 워크스페이스의 최상위 역할이 필요합니다. |
cert_revoke_target_denied# | 현재 사용자는 이 인증서의 요청자가 아니며 인증 기관의 서버를 관리할 권한도 없습니다. gate: server_reach에 해당합니다. | Revoking this certificate takes being its requester or holding manage access to its authority's server. 이 인증서를 폐기하려면 인증서의 요청자이거나 해당 인증 기관의 서버를 관리할 권한이 있어야 합니다. |
event_command_not_requester# | 다른 사람이 요청한 명령어입니다. | Your account may not act on this command, which it did not request. 본인이 요청한 명령어가 아니므로 현재 계정으로는 이 명령어에 대한 작업을 수행할 수 없습니다. |
approval_request_not_approver# | 현재 계정으로는 이 승인 요청을 승인하거나 거절할 수 없습니다. | Your account may not decide this request. 현재 계정으로는 이 요청을 승인하거나 거절할 수 없습니다. |
approval_request_not_requester# | 승인 요청을 낸 사용자만 해당 요청을 취소할 수 있습니다. | Your account may not cancel this request, which it did not raise. 본인이 낸 요청이 아니므로 현재 계정으로는 이 요청을 취소할 수 없습니다. |
local_access_claim_not_maintainer# | 이 로그인이 애플리케이션의 자동화 작업이었다고 확인하려면 해당 애플리케이션을 관리하는 사용자여야 합니다. | Only someone who maintains the application this account belongs to may claim this login as its automation. 이 계정이 속한 애플리케이션을 관리하는 사용자만 이 로그인이 애플리케이션의 자동화 작업이었다고 확인할 수 있습니다. |
토큰과 자격 증명
| 코드 | 의미 | 조치 |
|---|---|---|
api_token_scope_missing# | 토큰에 이 작업에 필요한 scope가 없습니다. gate: token_scope에 해당하며, missing에 scope: 접두사와 함께 필요한 scope가 표시됩니다. | This token does not hold a scope this action needs; use a token that has the scope, then retry. 이 토큰에는 작업에 필요한 scope가 없으므로 해당 scope가 있는 토큰으로 다시 시도하세요. 토큰에 필요한 scope를 추가하세요. scope를 변경하려면 승인이 필요할 수 있습니다. |
api_token_scope_action_unresolved# | 이 작업에 대응하는 토큰 scope가 없어 어떤 토큰으로도 이 작업을 수행할 수 없습니다. gate: token_scope에 해당합니다. | No token scope could be worked out for this action, so a token may not perform it; perform it from a console sign-in instead. 이 작업에 필요한 토큰 scope를 확인할 수 없어 토큰으로는 작업을 수행할 수 없습니다. 웹 콘솔에 로그인하여 작업을 수행하세요. |
api_token_acl_not_allowed# | 토큰의 접근 제어 규칙에서 이 요청을 허용하지 않습니다. 서버 규칙(gate: server_reach), 명령어 규칙(gate: command_acl, missing: command_preapproval) 또는 파일 규칙(gate: file_acl, missing: file_preapproval)에 해당합니다. | server_reach 게이트: This token's server access rules do not cover this server. command_acl 게이트: This token's command access rules do not pre-approve this command. file_acl 게이트: This token's file access rules do not allow this transfer for this path, account and direction. server_reach 게이트: 이 토큰의 서버 접근 제어 규칙에서 해당 서버를 허용하지 않습니다. command_acl 게이트: 이 토큰의 명령어 접근 제어 규칙에 해당 명령어에 대한 사전 승인 항목이 없습니다. file_acl 게이트: 이 토큰의 파일 접근 제어 규칙에서 해당 경로, 계정, 전송 방향으로 파일을 전송하는 것을 허용하지 않습니다. 토큰의 서버, 명령어 또는 파일 접근 제어 목록에 일치하는 규칙을 추가하세요. |
agent_credential_not_accepted# | 서버의 에이전트 자격 증명으로 허용되지 않는 요청을 보냈습니다. gate: role, missing: role에 해당합니다. | A server's agent credential cannot make this request; make it as a person or with an API token instead. 서버의 에이전트 자격 증명으로는 이 요청을 보낼 수 없습니다. 사용자로 요청하거나 API 토큰으로 요청하세요. |
api_not_for_alpacon# | 이 경로에서는 서버의 에이전트 자격 증명을 허용하지 않습니다. | This request is not open to a server's agent credential. 서버의 에이전트 자격 증명으로는 이 요청을 보낼 수 없습니다. |
local_access_principal_not_supported# | 이 작업은 웹 콘솔에 로그인한 사람만 수행할 수 있으며, API 토큰과 서비스 토큰은 거부됩니다. gate: presence에 해당합니다. | Only a person signed in to the console can do this; an API or service token cannot. 웹 콘솔에 로그인한 사람만 이 작업을 수행할 수 있습니다. API 토큰이나 서비스 토큰으로는 수행할 수 없습니다. |
auth_interactive_channel_requires_presence# | 토큰으로 Websh, 편집기 또는 WebFTP 세션을 열려고 했습니다. | This credential cannot stand for a person at the keyboard, so it cannot open a Websh, editor or WebFTP session; sign in to the CLI or the web console instead. 이 자격 증명으로는 직접 조작하는 사람임을 확인할 수 없어 Websh, 편집기 또는 WebFTP 세션을 열 수 없습니다. CLI나 웹 콘솔에 로그인하세요. |
auth_mfa_requires_human_principal# | 토큰이나 에이전트로 새로운 MFA 인증이 필요한 작업을 시도했습니다. | This action needs a fresh MFA check, which only a person can give; perform it as a signed-in person instead. 이 작업에는 사람이 직접 수행하는 새로운 MFA 인증이 필요합니다. 사용자로 로그인한 뒤 작업을 수행하세요. |
cert_principal_not_supported# | 서비스 토큰이나 에이전트로 인증서 발급을 요청하려고 했습니다. | A certificate request records the person who filed it, so a service token or an agent cannot file one; file it as a person. 인증서 발급 요청에는 요청한 사람이 기록되므로 서비스 토큰이나 에이전트로는 요청할 수 없습니다. 사용자로 요청하세요. |
cloud_principal_not_supported# | 서비스 토큰으로 클라우드 계정, 클라우드 인스턴스, 설치 작업 API를 호출했습니다. 조회도 거절됩니다. | 클라우드 계정, 인스턴스, 설치 작업은 사람만 사용할 수 있으므로 서비스 토큰으로는 조회하거나 변경할 수 없습니다. 사용자로 진행하세요. |
package_principal_not_supported# | 서비스 토큰으로 패키지를 만들거나 패키지에 파일을 올리려고 했습니다. | A package and its entries record the person who uploaded them, so a service token cannot create one; do it as a person. 패키지와 그 안의 파일에는 올린 사람이 기록되므로 서비스 토큰으로는 만들 수 없습니다. 사용자로 진행하세요. |
metrics_alert_rule_agent_not_allowed# | 에이전트 자격 증명으로 알림 규칙을 생성하려고 했습니다. | An agent credential cannot create an alert rule; create it as a person instead. 에이전트 자격 증명으로는 알림 규칙을 생성할 수 없습니다. 사용자로 생성하세요. |
kube_audit_not_a_cluster# | 등록된 클러스터에 속하지 않는 에이전트가 Kubernetes 감사 이벤트를 보고하려고 했습니다. | Only a registered cluster's agent may report Kubernetes audit events. 등록된 클러스터의 에이전트만 Kubernetes 감사 이벤트를 보고할 수 있습니다. |
kube_session_policy_not_a_cluster# | 등록된 클러스터에 속하지 않는 에이전트가 Kubernetes 세션의 제한 사항을 읽으려고 했습니다. | Only a registered cluster's agent may read a Kubernetes session's limits. 등록된 클러스터의 에이전트만 Kubernetes 세션의 제한 사항을 읽을 수 있습니다. |
sudo_verify_credential_cannot_prove_mfa# | sudo 요청을 검증하는 데 쓴 자격 증명으로는 MFA 인증을 증명할 수 없습니다. gate: presence에 해당합니다. | This credential cannot prove an MFA check; verify the sudo request from a console or CLI sign-in instead. 이 자격 증명으로는 MFA 인증을 증명할 수 없습니다. 웹 콘솔이나 CLI에 로그인한 뒤 sudo 요청을 검증하세요. |
MFA 검사
| 코드 | 의미 | 조치 |
|---|---|---|
auth_mfa_required# | 이 작업을 수행하려면 최근에 완료한 MFA 인증이 필요합니다. gate: presence, missing: presence에 해당합니다. | This action needs a recent MFA check; complete MFA, then retry. 이 작업을 수행하려면 최근에 완료한 MFA 인증이 필요합니다. MFA 인증을 완료한 뒤 다시 시도하세요. |
sudo_policy_bypass_agent_session_needs_presence# | 에이전트 세션의 작업 세션으로 허용된 sudo 정책을 변경하려면 새로운 MFA 인증이 필요합니다. gate: presence, missing: presence에 해당합니다. | Changing a session-authorized sudo policy on an agent session needs a fresh MFA check; complete MFA, then retry. 에이전트 세션의 작업 세션으로 허용된 sudo 정책을 변경하려면 새로운 MFA 인증이 필요합니다. MFA 인증을 완료한 뒤 다시 시도하세요. |
workspace_execution_control_mode_presence_required# | 실행 제어 모드를 변경하려면 새로운 MFA 인증이 필요합니다. | Changing the execution control mode needs a fresh MFA check; complete MFA, then retry. 실행 제어 모드를 변경하려면 새로운 MFA 인증이 필요합니다. MFA 인증을 완료한 뒤 다시 시도하세요. |
workspace_sudo_with_mfa_step_up_unavailable# | 현재 Alpacon 환경에서는 sudo MFA 인증을 진행할 수 없어 워크스페이스의 sudo 설정을 변경할 수 없습니다. gate: presence에 해당합니다. | This Alpacon deployment cannot run the sudo MFA check, so sudo through Alpacon cannot be changed here. 현재 Alpacon 환경에서는 sudo MFA 인증을 진행할 수 없어 Alpacon을 통한 sudo 실행 설정을 변경할 수 없습니다. |
workspace_block_local_sudo_step_up_unavailable# | 현재 Alpacon 환경에서는 sudo MFA 인증을 진행할 수 없어 로컬 sudo를 차단할 수 없습니다. gate: presence에 해당합니다. | This Alpacon deployment cannot run the sudo MFA check, so local sudo cannot be blocked here. 현재 Alpacon 환경에서는 sudo MFA 인증을 진행할 수 없어 로컬 sudo를 차단할 수 없습니다. |
승인과 작업 세션
| 코드 | 의미 | 조치 |
|---|---|---|
approval_requester_may_not_approve# | 본인이 낸 요청을 승인하거나 거절하려고 했습니다. gate: approval, missing: other_approver에 해당합니다. | You cannot decide a request you raised; it needs a decision from someone other than you. 본인이 낸 요청은 직접 승인하거나 거절할 수 없습니다. 다른 사람이 승인 또는 거절해야 합니다. |
sudo_policy_bypass_agent_session_needs_approval# | 에이전트 세션에 작업 세션으로 허용된 sudo 정책을 추가하려면 사람의 승인이 필요합니다. gate: approval, missing: approval에 해당합니다. | A session-authorized sudo policy on an agent session needs approval; add it as a change to the work session so that a person can approve it. 에이전트 세션의 작업 세션으로 허용된 sudo 정책에는 승인이 필요합니다. 사람이 승인할 수 있도록 작업 세션의 변경 사항으로 추가하세요. |
work_session_account_not_approved# | 에이전트 세션에서 승인받지 않은 계정으로 실행하려고 했습니다. gate: work_session, missing: approved_account에 해당합니다. | This agent session runs only as the account its approval covered; use that account, or request a work session for the account you need. 이 에이전트 세션에서는 승인받은 계정으로만 실행할 수 있습니다. 해당 계정을 쓰거나 필요한 계정으로 작업 세션을 요청하세요. |
work_session_agent_not_allowed# | 워크스페이스의 승인 정책에서 이 에이전트를 허용하지 않습니다. gate: approval, missing: allowed_agent에 해당합니다. | The workspace's approval policy does not allow this agent; use an agent the policy allows. 워크스페이스의 승인 정책에서 이 에이전트를 허용하지 않습니다. 정책에서 허용하는 에이전트를 쓰세요. |
콘솔 전용 작업
| 코드 | 의미 | 조치 |
|---|---|---|
access_rules_console_only# | 접근 규칙은 웹 콘솔에서만 조회할 수 있습니다. | Access rules are answered only in the web console, not to the CLI, MCP or a token; use the console instead. 접근 규칙은 웹 콘솔에서만 조회할 수 있으며 CLI, MCP 또는 토큰으로는 조회할 수 없습니다. 웹 콘솔을 쓰세요. |
ai_agent_attach_console_only# | AI 에이전트 자격 증명은 웹 콘솔에서만 연결할 수 있습니다. | AI agent credentials can be attached only from the web console; use the console instead. AI 에이전트 자격 증명은 웹 콘솔에서만 연결할 수 있습니다. 웹 콘솔에서 작업하세요. |
approval_policy_console_only# | 승인 정책은 웹 콘솔에서만 읽거나 변경할 수 있습니다. | Approval policies can be read and changed only from the web console; use the console instead. 승인 정책은 웹 콘솔에서만 읽거나 변경할 수 있습니다. 웹 콘솔에서 작업하세요. |
group_agent_approval_console_only# | 에이전트 승인이 필요한 그룹은 웹 콘솔에서만 변경할 수 있습니다. | Which group needs agent approval can be changed only from the web console; use the console instead. 에이전트 승인이 필요한 그룹은 웹 콘솔에서만 변경할 수 있습니다. 웹 콘솔에서 작업하세요. |
sudo_policy_console_only# | sudo 정책은 웹 콘솔에서만 생성하거나 허용 범위를 넓힐 수 있습니다. | A sudo policy can be created or widened only from the web console; make the change there. sudo 정책은 웹 콘솔에서만 생성하거나 허용 범위를 넓힐 수 있습니다. 웹 콘솔에서 변경하세요. |
work_session_sudo_bypass_console_only# | 작업 세션에 작업 세션으로 허용된 sudo 정책을 추가하는 작업은 웹 콘솔에서만 수행할 수 있습니다. | A session-authorized sudo policy can be added to a work session only from the web console; add it there. 작업 세션에 작업 세션으로 허용된 sudo 정책을 추가하는 작업은 웹 콘솔에서만 수행할 수 있습니다. 웹 콘솔에서 추가하세요. |
workspace_execution_control_console_only# | 실행 제어는 웹 콘솔에서만 완화할 수 있습니다. | Loosening execution control can be done only from the web console; make the change there. 실행 제어는 웹 콘솔에서만 완화할 수 있습니다. 웹 콘솔에서 변경하세요. |
workspace_security_settings_console_only# | 워크스페이스의 MFA 정책은 웹 콘솔에서만 완화할 수 있습니다. | Weakening the workspace's MFA policy can be done only from the web console; make the change there. 워크스페이스의 MFA 정책은 웹 콘솔에서만 완화할 수 있습니다. 웹 콘솔에서 변경하세요. |
workspace_force_delete_portal_only# | 워크스페이스 강제 삭제 요청은 Alpacon 포털에서만 받습니다. | A forced workspace deletion is accepted only from the Alpacon portal. 워크스페이스를 강제로 삭제하려면 Alpacon 포털에서 요청해야 합니다. |
405로 거부되는 메서드
| 코드 | 의미 | 조치 |
|---|---|---|
workspace_put_info_disabled# | 워크스페이스 상세 정보에 대한 PUT 요청이 405 응답과 함께 거부됩니다. | The workspace's details take partial updates only; send the change as a PATCH instead. 워크스페이스 상세 정보는 부분 변경만 지원합니다. PATCH로 변경 사항을 보내세요. |
command_acl_moved# | 현재 Alpacon 환경에서는 Alpacon AI가 명령어 ACL을 관리하므로 해당 경로에서 405를 반환합니다. | Command ACLs are managed by Alpacon AI on this deployment, so they cannot be changed here. 현재 Alpacon 환경에서는 Alpacon AI가 명령어 ACL을 관리하므로 여기서는 변경할 수 없습니다. |
워크스페이스 상태
| 코드 | 의미 | 조치 |
|---|---|---|
workspace_suspended# | 워크스페이스가 정지되었습니다. | This workspace is suspended, so changes are refused until its plan is downgraded or renewed. 이 워크스페이스는 정지된 상태입니다. 플랜을 하위 플랜으로 변경하거나 갱신하기 전에는 변경 요청이 거부됩니다. |
workspace_unclaimed# | 첫 소유자를 위해 미리 설정된 워크스페이스이며, 첫 소유자가 아직 소유권을 받지 않았습니다. | This workspace is not claimed yet, so only the person invited to claim it may join. 첫 소유자가 아직 이 워크스페이스의 소유권을 받지 않아 소유권을 받도록 초대받은 사람만 참여할 수 있습니다. |
workspace_not_unclaimed# | 첫 소유자가 아직 소유권을 받지 않은 워크스페이스에서만 수행할 수 있는 작업이지만, 이 워크스페이스의 첫 소유자는 이미 소유권을 받았습니다. | This action needs a workspace that is not claimed yet. 이 작업은 첫 소유자가 아직 소유권을 받지 않은 워크스페이스에서만 수행할 수 있습니다. |
workspace_extension_not_enabled# | 이 확장 기능은 워크스페이스의 플랜에 포함되어 있지만 꺼져 있습니다. | This extension is on the workspace's plan but switched off; it has to be turned on in the workspace's settings first. 이 확장 기능은 워크스페이스의 플랜에 포함되어 있지만 꺼져 있습니다. 먼저 워크스페이스 설정에서 켜세요. |
플랜 한도
이 코드들은 gate: "plan"와 함께 402를 반환합니다. axis, next, Retry-After는
플랜 한도에 따른 요청 거부를 참고하세요.
| 코드 | 의미 | 조치 |
|---|---|---|
server_limit_exceeded# | 워크스페이스가 플랜의 서버 수 한도에 도달했습니다(axis: server). gate: plan에 해당합니다. | The workspace has reached its plan's server limit, so a new server is refused while existing ones keep working; it needs a free slot or a plan with a higher limit. 워크스페이스가 플랜의 서버 수 한도에 도달하여 새 서버를 추가할 수 없습니다. 기존 서버는 계속 작동합니다. 서버를 추가하려면 한도에 여유가 생기도록 하거나 한도가 더 높은 플랜으로 변경해야 합니다. |
user_limit_exceeded# | 대기 중인 초대를 포함해 워크스페이스가 플랜의 사용자 수 한도에 도달했습니다(axis: user). gate: plan에 해당합니다. | The workspace has reached its plan's user limit, pending invitations included; it needs a free seat or a plan with a higher limit. 대기 중인 초대를 포함해 워크스페이스가 플랜의 사용자 수 한도에 도달했습니다. 시트에 여유가 생기도록 하거나 한도가 더 높은 플랜으로 변경해야 합니다. |
application_limit_exceeded# | 워크스페이스가 플랜의 애플리케이션 수 한도에 도달했습니다(axis: application). gate: plan에 해당합니다. | The workspace has reached its plan's application limit; it needs a free slot or a plan with a higher limit. 워크스페이스가 플랜의 애플리케이션 수 한도에 도달했습니다. 한도에 여유가 생기도록 하거나 한도가 더 높은 플랜으로 변경해야 합니다. |
websh_limit_exceeded# | 워크스페이스가 이번 사용 기간에 플랜에서 제공하는 Websh 시간을 모두 썼습니다(axis: websh). gate: plan에 해당합니다. | The workspace's plan allows no more Websh time in this period, so new sessions are refused while running ones continue. 이번 사용 기간에 워크스페이스의 플랜에서 제공하는 Websh 시간을 모두 써서 새 세션을 열 수 없습니다. 실행 중인 세션은 계속 유지됩니다. 이번 사용 기간이 끝날 때까지 Retry-After에 표시된 초 수만큼 기다리세요. |
webftp_limit_exceeded# | 워크스페이스가 이번 사용 기간에 플랜에서 제공하는 WebFTP 전송량을 모두 썼습니다(axis: webftp). gate: plan에 해당합니다. | The workspace's plan allows no more WebFTP transfer volume in this period, so new transfers are refused. 이번 사용 기간에 워크스페이스의 플랜에서 제공하는 WebFTP 전송량을 모두 써서 새 전송 요청이 거부됩니다. 이번 사용 기간이 끝날 때까지 Retry-After에 표시된 초 수만큼 기다리세요. |
websh_share_limit_exceeded# | 플랜에 Websh 공유가 포함되어 있지 않거나 이번 사용 기간의 공유 시간을 모두 썼습니다(axis: websh-share). gate: plan에 해당합니다. | The workspace's plan does not include Websh sharing, or its sharing time for this period is used up. 워크스페이스의 플랜에 Websh 공유가 포함되어 있지 않거나 이번 사용 기간의 공유 시간을 모두 썼습니다. 응답에 Retry-After가 있으면 표시된 초 수만큼 기다린 뒤 다시 공유할 수 있습니다. |
workspace_free_limit_exceeded# | 두 번째 Free 워크스페이스를 생성하려고 했습니다(axis: workspace). gate: plan에 해당합니다. | You already have a Free workspace you signed up for, and an account can hold only one. 직접 가입하여 만든 Free 워크스페이스가 이미 있습니다. 계정 하나당 Free 워크스페이스는 하나만 보유할 수 있습니다. |
workspace_enterprise_plan_required# | 이 기능에는 Enterprise 플랜이 필요합니다. gate: plan에 해당합니다. | This needs the Enterprise plan, which the workspace is not on. 이 작업에는 Enterprise 플랜이 필요하지만 현재 워크스페이스는 해당 플랜을 쓰고 있지 않습니다. |
workspace_slug_change_requires_enterprise# | 워크스페이스 주소를 변경하려면 Enterprise 플랜이 필요합니다. gate: plan에 해당합니다. | Changing the workspace's address needs the Enterprise plan. 워크스페이스 주소를 변경하려면 Enterprise 플랜이 필요합니다. |
workspace_extension_plan_required# | 워크스페이스의 플랜에 이 확장 기능이 포함되어 있지 않습니다. gate: plan에 해당합니다. | The workspace's plan does not include this extension; it needs a plan that does. 워크스페이스의 플랜에 이 확장 기능이 포함되어 있지 않습니다. 해당 확장 기능이 포함된 플랜이 필요합니다. |
workspace_plan_update_required# | 워크스페이스의 플랜에 이 기능이 포함되어 있지 않습니다. gate: plan에 해당합니다. | The workspace's plan does not include this; it needs a plan that does. 워크스페이스의 플랜에 이 기능이 포함되어 있지 않습니다. 해당 기능이 포함된 플랜이 필요합니다. |
요청 한도에 따른 거부
이 코드들은 gate: "rate"와 함께 429를 반환합니다. 서비스 토큰의 요청 한도는
요청 한도를 참고하세요.
| 코드 | 의미 | 조치 |
|---|---|---|
api_rate_limited# | 호출자가 요청 한도를 초과했습니다. gate: rate에 해당합니다. | Too many requests were made in a short time; wait, then retry. 짧은 시간에 너무 많은 요청을 보냈습니다. 잠시 기다린 뒤 다시 시도하세요. 재시도하기 전에 Retry-After에 표시된 초 수만큼 기다리세요. |
rag_rate_limit_exceeded# | 짧은 시간에 AI 어시스턴트 요청을 너무 많이 보냈습니다. gate: rate에 해당합니다. | Too many assistant requests were made in a short time; wait, then retry. 짧은 시간에 AI 어시스턴트 요청을 너무 많이 보냈습니다. 잠시 기다린 뒤 다시 시도하세요. 재시도하기 전에 Retry-After에 표시된 초 수만큼 기다리세요. |
workspace_invite_rate_limited# | 짧은 시간에 초대를 너무 많이 보냈습니다. gate: rate에 해당합니다. | Too many invitations were sent in a short time; wait, then send again. 짧은 시간에 초대를 너무 많이 보냈습니다. 잠시 기다린 뒤 다시 보내세요. |
confirm_token_resend_limit_exceeded# | 확인 메시지를 허용된 횟수만큼 모두 재전송했습니다. gate: rate에 해당합니다. | This confirmation has been resent as many times as allowed; wait, then try again. 이 확인 메시지를 허용된 횟수만큼 모두 재전송했습니다. 잠시 기다린 뒤 다시 시도하세요. |
서비스 토큰으로 자동화하기
alpacon-cli 1.14.2 이상과 Bash, curl, jq를 준비하세요. alpacon login으로 슈퍼유저 또는 관리자로 로그인하고, 아래 ALPACON_URL과 같은 워크스페이스를 선택합니다. alpacon api는 로그인한 세션으로 요청하며, 필요하면 MFA 확인을 안내합니다. 응답 본문은 stdout에 출력합니다. HTTP 오류가 발생하면 stderr에도 HTTP <code>를 출력하고 종료 코드 1로 끝납니다.
3단계, 5b단계, 6단계와 자체 호스팅의 7단계에는 로그인 세션이 필요합니다. 1·2·4단계는 필요한 scope를 갖춘 본인의 개인 API 토큰으로도 호출할 수 있지만 서비스 토큰으로는 호출할 수 없습니다. 이 가이드에서는 해당 요청을 모두 로그인한 CLI 세션으로 보내세요. CLI에서 생성한 서비스 토큰은 항상 웹 콘솔에서 승인을 기다립니다. 5a단계의 승인은 웹 콘솔에서만 할 수 있으며, Cloud의 7단계도 콘솔에서 진행합니다.
워크스페이스 URL과 Linux 서버 하나의 ID를 설정하세요. 서버는 최신 에이전트 설치를 마치고 연결된 상태여야 합니다. 나머지 변수는 단계를 따라가며 채우세요. 응답 예시는 주요 필드만 보여주며, ID와 시각은 설명을 위한 값입니다.
alpacon login
ALPACON_URL='https://your-workspace.ap1.alpacon.io'
SERVICE_TOKEN=''
APP_ID=''
ROLE_ID=''
TOKEN_ID=''
APPROVAL_REQUEST_ID=''
SERVER_ID=''
COMMAND_ID=''
read -r -p 'Connected server ID: ' SERVER_ID1. 애플리케이션 생성
서버 계정을 설정하기 전에 이름이 CI pipeline이고 서비스 유형이 ci_cd인 애플리케이션을 만드세요.
alpacon api -X POST /api/iam/applications/ \
-f 'name=CI pipeline' -f service_type=ci_cd예상 결과: 201 Created.
{"id":"<application-id>","name":"CI pipeline","service_type":"ci_cd","username":null,"shell":"/usr/sbin/nologin","provisioning_enabled":false,"auto_provisioning":false}애플리케이션의 id를 저장하세요.
read -r -p 'Application ID: ' APP_ID2. 애플리케이션의 서버 계정 설정
애플리케이션의 사용자 이름을 ci-deploy로 정하고 프로비저닝을 켜세요. 기존 서버 계정이나 그룹과 겹치지 않는 이름을 사용합니다. 최신 에이전트가 실행 중인 Linux 서버에서는 첫 명령을 실행할 때 계정을 만듭니다.
alpacon api -X PATCH "/api/iam/applications/$APP_ID/" \
-f username=ci-deploy -F provisioning_enabled=true예상 결과: 200 OK와 수정된 애플리케이션.
{"id":"<application-id>","username":"ci-deploy","provisioning_enabled":true}기존 계정이나 그룹과 이름이 겹치면 400 approval_superuser_approve_required가 돌아옵니다. 승인을 완료한 뒤 다음 단계로 넘어가세요. 기존 서버 계정을 연결하려면 애플리케이션의 서버 계정 연결 API를 참고하세요.
3. 애플리케이션에 전역 역할 부여
애플리케이션에 기본 제공 역할인 operator를 전역으로 부여하세요. 특정 리소스로 범위를 제한하지 않습니다. 이 역할에는 command:create와 command:read가 포함됩니다. 작업하는 사람은 애플리케이션을 수정할 수 있어야 하며, 이 역할의 권한을 부여할 수 있어야 합니다. 토큰의 scope는 애플리케이션의 전역 역할이 허용하는 범위 안에 있어야 합니다.
3a. 역할 찾기:
alpacon api -X GET /api/rbac/roles/ -f name=operator예상 결과: 200 OK. results에 역할이 포함됩니다.
{"results":[{"id":"<role-id>","name":"operator"}]}역할의 id를 ROLE_ID에 저장하세요.
read -r -p 'Operator role ID: ' ROLE_ID3b. 역할 부여: content_type과 object_id를 생략하세요. 역할을 부여하려면 MFA를 새로 확인해야 합니다. alpacon api가 안내하는 MFA 확인을 완료하세요. 새로 확인하지 않으면 API가 401 auth_mfa_required와 source: "rbac_binding"을 반환합니다.
alpacon api -X POST /api/rbac/application-roles/ \
-f "application=$APP_ID" -f "role=$ROLE_ID"예상 결과: 201 Created.
{"id":"<grant-id>","application":{"id":"<application-id>","name":"CI pipeline"},"role":{"id":"<role-id>","name":"operator"},"content_type":null,"object_id":null}4. 서비스 토큰 생성
이름이 ci-deploy이고 scope가 command:create, command:read인 서비스 토큰을 만드세요. 미래의 만료 시각을 설정하고 사유로 Run deployment checks from CI를 입력합니다. 아래 예시의 만료 시각도 실제로 사용할 때 미래여야 합니다.
alpacon api -X POST /api/auth/service-tokens/tokens/ \
-f name=ci-deploy -f "application=$APP_ID" \
-f 'scopes[]=command:create' -f 'scopes[]=command:read' \
-f expires_at=2027-01-01T00:00:00Z \
-f 'justification=Run deployment checks from CI'명령 scope의 위험도는 중간이며, 비어 있지 않은 justification이 필요합니다. 이 scope로 토큰을 생성하면 항상 202 Accepted와 승인 대기 중인 토큰이 돌아옵니다.
{"id":"<token-id>","name":"ci-deploy","application":{"id":"<application-id>","name":"CI pipeline","service_type":"ci_cd","username":"ci-deploy"},"key":"alpst-…","enabled":false,"activation_state":"pending","scopes":["command:create","command:read"],"expires_at":"2027-01-01T00:00:00Z","rotation_policy":"90d","status":"pending_approval","risk_level":"medium","approval_request_id":"<approval-request-id>"}지금 key를 안전한 곳에 저장하세요. 이후 GET 응답에서는 키를 다시 보여주지 않습니다. 토큰 ID와 승인 요청 ID도 저장합니다. 승인 대기 중인 키는 아직 인증에 사용할 수 없습니다.
read -r -p 'Service token ID: ' TOKEN_ID
read -r -p 'Approval request ID: ' APPROVAL_REQUEST_ID
read -r -s -p 'Service token key: ' SERVICE_TOKEN
printf '\n'5. 토큰 승인 및 활성 상태 확인
5a. 웹 콘솔에서 승인: 토큰은 웹 콘솔에서만 승인할 수 있습니다. https://<workspace-console>/<workspace>/approvals?selected=$APPROVAL_REQUEST_ID에서 콘솔 호스트와 워크스페이스는 실제 값으로, $APPROVAL_REQUEST_ID는 4단계에서 저장한 ID로 바꿔 요청을 여세요. 또는 대기 중인 승인으로 이동해 해당 요청의 서비스 토큰 생성 행을 선택하세요. 슈퍼유저 또는 그 요청의 승인자가 승인합니다. 승인 정책이 금지하지 않으면 요청자도 자신의 요청을 승인할 수 있습니다. MFA를 새로 확인하라는 안내가 나오면 완료하세요. 정책에서 추가 승인을 요구하면 승인이 완료될 때까지 기다립니다.
5b. 활성 상태 확인: CLI로 돌아와 토큰을 조회하세요.
alpacon api -X GET "/api/auth/service-tokens/tokens/$TOKEN_ID/"예상 결과: 200 OK. scope_usage가 포함되며 key는 없습니다.
{"id":"<token-id>","activation_state":"active","enabled":true,"scopes":["command:create","command:read"]}6. 서버 허용
승인을 마친 뒤 토큰의 접근 규칙에서 SERVER_ID에 지정한 서버를 허용하세요. ACL을 추가하거나 수정하려면 대상 토큰이 승인되고 활성화되어 있어야 합니다. 승인 대기 중이거나 비활성화된 토큰을 지정하면 service_token 필드에 400 does_not_exist가 돌아옵니다.
alpacon api -X POST /api/security/server-acl/ \
-f "service_token=$TOKEN_ID" -f "server=$SERVER_ID"예상 결과: 201 Created.
{"id":"<server-acl-id>","token":null,"service_token":"<token-id>","token_name":"ci-deploy","server":{"id":"<server-id>","name":"deploy-server","is_connected":true,"is_deleted":false}}7. 명령 허용
Alpacon Cloud에서는 웹 콘솔의 토큰 페이지에서 접근 규칙 탭(?tab=acl)을 선택하세요. 사전 승인된 명령에서 추가를 누르면 명령 추가 대화상자가 열립니다. 목록을 명령 ACL 관리자가 관리한다는 안내가 나오면 관리자에게 권한을 요청하세요. 브라우저에 연결 안내가 나오면 연결하기를 선택하세요. 연결은 처음 한 번만 필요할 수 있습니다.
대화상자의 명령에 df -h를 입력하세요. 실행 계정에는 모든 계정을 허용하는 *나 ci-deploy를 입력합니다. 그룹을 제한하려면 그룹을 설정하세요. 특정 서버에만 적용하려면 서버에서 서버를 선택합니다. 아무 서버도 선택하지 않으면 이 토큰이 닿는 모든 서버에 규칙이 적용됩니다. 명령이 목록에 표시되는지 확인하세요. Cloud에서 ACL API가 반환하는 명령 ACL 행은 토큰으로 실행할 수 있는 명령을 결정하지 않습니다. 이 API에 쓰기 요청을 보내면 405 command_acl_moved가 돌아옵니다.
자체 호스팅 배포에서는 토큰의 명령 접근 규칙에 df -h를 허용하세요.
alpacon api -X POST /api/security/command-acl/ \
-f "service_token=$TOKEN_ID" -f 'command=df -h'자체 호스팅 배포의 예상 결과: 201 Created.
{"id":"<command-acl-id>","token":null,"service_token":"<token-id>","token_name":"ci-deploy","command":"df -h","username":"","groupname":""}username과 groupname이 비어 있으면 이 규칙에 계정 제한을 추가하지 않습니다. 명령은 여전히 2단계에서 설정한 애플리케이션 계정으로 실행됩니다.
8. 토큰으로 명령 실행
승인된 토큰으로 명령 API를 호출합니다. 작업 세션은 필요하지 않습니다. username과 groupname을 생략하면 애플리케이션 계정으로 실행됩니다. 에이전트 설치를 마치고 연결된 server 하나를 지정하세요. 서버가 연결되지 않았다면 요청에 400 server_not_connected가 돌아오고, 에이전트 설치를 마치지 않았다면 400 server_not_commissioned가 돌아옵니다.
server 필드의 400 does_not_exist는 서버가 토큰의 서버 접근 규칙에 없거나 존재하지 않는다는 뜻입니다. SERVER_ID를 확인하고 6단계로 돌아가세요. 400 application_system_user_not_found는 애플리케이션 계정을 만들 수 없다는 뜻입니다. 2단계의 조건에 맞게 최신 에이전트가 실행 중인 Linux 서버를 사용하세요.
COMMAND_RESPONSE=$(curl --fail-with-body --silent --show-error \
-X POST "$ALPACON_URL/api/events/commands/" \
-H "Authorization: token=\"$SERVICE_TOKEN\"" \
-H 'Content-Type: application/json' \
-d "{\"server\":\"$SERVER_ID\",\"line\":\"df -h\",\"purpose\":\"Check disk space before deploying\"}")
printf '%s\n' "$COMMAND_RESPONSE" | jq .
COMMAND_ID=$(printf '%s' "$COMMAND_RESPONSE" | jq -er '.[0].id')예상 결과: 201 Created와 항목이 하나인 목록. 프로비저닝을 켠 뒤 첫 명령은 계정 설정 명령이 끝날 때까지 기다립니다. 이때 status는 queued이고 run_after에는 앞서 실행한 명령의 ID가 들어갑니다. 진행 상황에 따라 처음 조회되는 상태는 다를 수 있습니다. 요청을 접수했다고 실행이 끝난 것은 아닙니다.
[{"id":"<command-id>","line":"df -h","purpose":"Check disk space before deploying","username":"ci-deploy","groupname":"ci-deploy","status":"queued","run_after":["<account-setup-command-id>"],"request_channel":"service_token","work_session":null,"service_token":"<token-id>","application":"<application-id>"}]9. 상태 조회 및 명령 기록 확인
status가 completed, rejected, denied 중 하나가 될 때까지 상세 조회를 반복합니다.
HEADERS=$(mktemp)
BODY=$(mktemp)
while true; do
HTTP_STATUS=$(curl --silent --show-error \
--dump-header "$HEADERS" --output "$BODY" --write-out '%{http_code}' \
"$ALPACON_URL/api/events/commands/$COMMAND_ID/" \
-H "Authorization: token=\"$SERVICE_TOKEN\"") || break
if [ "$HTTP_STATUS" = 429 ]; then
RETRY_AFTER=$(awk 'tolower($1) == "retry-after:" { print $2 + 0 }' "$HEADERS")
sleep "${RETRY_AFTER:-60}"
continue
fi
if [ "$HTTP_STATUS" != 200 ]; then
cat "$BODY"
break
fi
COMMAND_RECORD=$(cat "$BODY")
printf '%s\n' "$COMMAND_RECORD" | jq '{status, success, exit_code, result, elapsed_time, handled_at, rejection_cause, rejection_gate, rejected_at}'
COMMAND_STATUS=$(printf '%s' "$COMMAND_RECORD" | jq -er '.status') || break
case "$COMMAND_STATUS" in
completed|rejected|denied) break ;;
esac
sleep 5
done
rm -f "$HEADERS" "$BODY"반복문은 5초마다 조회해 시간당 720회로 기본 제한인 시간당 1000회를 넘지 않고, 429 응답을 받으면 Retry-After에 지정된 초만큼 기다렸다가 조회를 이어가므로 승인이 오래 걸리는 명령도 최종 기록까지 확인할 수 있습니다.
awaiting_approval은 웹 콘솔에서 승인자의 처리를 기다리는 상태이며, 이 동안에도 반복문은 계속 조회합니다.
각 GET의 예상 결과: 200 OK. 실행 중에는 status가 delivered 또는 running일 수 있으며 handled_at은 null입니다. 완료 응답에는 다음 필드가 포함됩니다.
{"id":"<command-id>","status":"completed","success":true,"exit_code":0,"result":"<command output>","elapsed_time":0.12,"acked_at":null,"handled_at":"2026-10-24T12:00:00Z","verification_status":"approved","risk_level":"LOW"}success를 먼저 읽고, 이어서 exit_code, result, elapsed_time, handled_at을 확인하세요. 명령이 완료되어도 acked_at은 null일 수 있습니다. 응답이 없는 명령을 타임아웃으로 종료한 경우에도 상태는 completed가 됩니다. 이때 success: false, exit_code: null이며 result에는 타임아웃 메시지가 들어갑니다.
status: "rejected"이면 rejection_cause, rejection_gate, rejected_at을, status: "denied"이면 result를 확인하세요. 별도 필드인 denied는 목록 응답에만 있고 이 상세 응답에는 없습니다. 그 밖의 대기·실행 상태는 명령 상태를 참고하세요.
이 상세 응답이 곧 명령 기록입니다. delivered_at, acked_at, handled_at, verification_status, risk_level, service_token, service_token_name, application, application_name, request_channel이 포함됩니다. 필드 설명은 명령 조회를 참고하세요.
Alpacon 주요 기능
다음 문서들은 각 API 컬렉션에 대한 세부 정보를 제공합니다.