Skip to Content
가이드Agent 연결

Agent 연결

이 문서는 Deplite의 인증·통신 흐름을 정확히 이해하고 싶을 때 읽으면 좋아요.
운영에 꼭 필요한 내용은 아니지만, 보안 검토나 트러블슈팅 시 큰 도움이 돼요.

전체 흐름

[1] Enrollment (1회) Agent → POST /agent/enroll (Bearer <enr_...>) ← { agentId, serverPublicKey } Agent 로컬: agent.id / agent.key / server.pub 저장 [2] 상시 연결 Agent → GET /agent/stream (SSE, 서명 헤더) ⇐ deploy / workflows-refresh / revoke / ping [3] 주기 작업 Agent → POST /agent/heartbeat (60초마다) Agent → POST /agent/workflows/report (변경 감지 시) [4] Job 실행 시 Server (SSE) → "deploy" event (ED25519 서명된 payload) Agent → POST /agent/jobs/:id/logs (JSONL, 64KB·1초 배치) Agent → POST /agent/jobs/:id/result

Enrollment

최초 1회만 발생해요.

POST /agent/enroll Authorization: Bearer enr_... Content-Type: application/json { "name": "my-agent", "publicKey": "-----BEGIN PUBLIC KEY-----\n...", "hostname": "prod-01", "os": "linux", "agentVersion": "0.2.0" }

서버는 agentId와 자신의 ED25519 serverPublicKey를 돌려줘요.
Agent는 이걸 받아서 ./creds/에 영구 저장하고, 이후엔 Enrollment Token이 더 이상 필요하지 않아요.

요청 서명 (Agent → Server)

Enrollment 이후 Agent가 서버로 보내는 모든 요청은 ED25519로 서명돼요.

X-Agent-Id: <agentId> X-Timestamp: 1717180800 X-Nonce: <16 bytes hex> X-Signature: <base64 ed25519 signature>

서명 대상(canonical string)은 다음과 같아요.

<timestamp> <nonce> <UPPERCASE-METHOD> <path-with-query> <sha256-hex-of-body>

서버는 다음을 검증해요.

  • X-Timestamp가 현재 시각 ±60초 범위인가
  • X-Nonce가 LRU 캐시(TTL 10분)에 없는가 (재생 공격 방지)
  • 서명이 Agent의 등록된 공개키로 검증되는가

SSE 이벤트

GET /agent/stream (요청 서명 헤더 + Accept: text/event-stream)

서버는 다음 종류의 SSE 이벤트를 보내요.

이벤트의미
deploy워크플로우 실행 명령. payload는 ED25519 서명된 CommandPayload JSON
workflows-refresh즉시 워크플로우 디렉토리를 재스캔
revoke이 Agent가 회수됨. 즉시 종료
ping연결 유지 신호

SSE 연결이 끊기면 Agent는 1초→2초→4초… 60초까지 지수 백오프로 재연결을 시도해요.
30초 동안 어떤 이벤트도 안 오면 유휴로 보고 강제 재연결해요.

Deploy 명령 검증 (Server → Agent)

{ "payload": "<base64-json>", "signature": "<base64-ed25519>" }

Agent는 다음을 확인해요.

  1. payload base64 디코딩 후 JSON 정규화 (정렬된 키)
  2. server.pub로 ED25519 검증
  3. issued_at이 현재 시각 ±60초인가
  4. nonce가 자체 LRU 캐시에 없는가

검증을 통과해야만 실제 워크플로우가 실행돼요.

Heartbeat

POST /agent/heartbeat { "agent_version": "0.2.0", "running_jobs": ["job-id-1"], "workflow_count": 5 }

60초 주기로 보내요.
대시보드의 Agent 상태(connected/disconnected)는 이걸로 갱신돼요.

워크플로우 보고

POST /agent/workflows/report { "workflows": [ { "name": "deploy-prod", "verboseSteps": ["build"], "secretsKeys": ["DB_URL"] } ] }

서버에는 워크플로우 메타데이터만(이름, verbose step 목록, 시크릿 키 이름) 보고돼요.
실제 YAML 내용·step 명령어·시크릿 값은 서버로 가지 않아요.

회수(Revoke)

대시보드에서 Agent를 revoke하거나, SSE revoke 이벤트를 받으면 Agent는 즉시 종료해요.
이후 같은 agent.key로는 재연결할 수 없어요. 새 Enrollment Token으로 다시 등록해야 해요.

다음으로

최종 수정 일자: