OpenTAG

Teknik sunum · MVP · Ekim 2026

OpenTAG: şirket IT ekipleri için yapay zekâ destekli IT destek asistanı

IT çalışanı sorunu Türkçe anlatır. Asistan şirketin sistemlerine şirketteki agent'lar üzerinden bağlanır, teşhis eder, değişikliği planlar ve preview'ını çıkarır, onay alınca uygular ve sonucu doğrular. Yönetim bizde, yetki ve veri şirkette.

Durum
Faz 1 tamamlandı, kabul senaryosu canlıda geçti
Sırada
Faz 2: onay, imzalı approval ticket, secret store
Teknoloji
Go platform ve agent, Next.js console, OpenCode fork
Son release
v0.1.5 · macOS, Windows, Linux paketleri

Gezinme: soldaki bölüm listesi, klavyede j / → sonraki bölüm, k / ← önceki bölüm, + projeksiyon için büyük yazı. Bu sayfadaki her ifade bugünkü kod için doğrudur ya da planlanan fazıyla işaretlidir.

02 · Problem ve yaklaşım

IT ekibi çok sayıda farklı sistemi yönetir; bilgi dağınık, değişiklik risklidir

Problem

  • Linux ve Windows sunucular, Kubernetes, veritabanları, HTTP API'ler ve e-posta aynı ekibin sorumluluğundadır. Her birinin komutları ve tuzakları ayrıdır.
  • Yöntem bilgisi kişilerde kalır; giriş seviyesindeki IT çalışanı riskli işlerde kıdemli birine bağımlıdır.
  • Genel amaçlı AI sohbetleri sistemlere dokunamaz: komut ve çıktılar elle kopyalanır, parolalar sohbete yapıştırılır.
  • Sınırsız shell yetkisi verilen bir AI agent ise onay, audit ve secret koruması olmadan çalışır.

Yaklaşım

  • Agent'lar şirkette çalışır. Tool'lar ve secret'lar IT çalışanının bilgisayarında ve şirket sunucusunda durur; platform müşteri sistemine kendisi dokunmaz.
  • Önce oku, sonra planla ve onayla yaz. Her write tool hedef, etki, rollback ve doğrulama içeren bir plan ister; mümkünse önce preview yapılır.
  • Secret değerleri modele ulaşmaz. Model yalnız secret:// referansı görür, çıktılar maskelenir.
  • Generic core. Ürüne özel kod yoktur; yeni bir sistem çoğu zaman yalnız bir skill'dir.
  • Öğrenen sistem. Çözülen sorun skill olarak kaydedilir ve şirket içinde paylaşılır.

Kimin için

Role (Zitadel project role)Ne yapar
sirket_adminiŞirketin admini: agent kurulum token'ı üretir, server agent'ları yönetir; Faz 2-3 ile shared connection'lar, policy, üyeler ve MCP server'lar. Bütün role kontrollerini geçer.
kidemli_itKıdemli IT: skill'leri şirket içinde paylaşır (Faz 3 kuralı), audit log'u görür (Faz 4).
itIT çalışanı: sohbetle çalışır. Role'üne kapalı capability'ler (ör. script) şirket policy'siyle kısıtlanır (Faz 2).

03 · Bugün ve plan

Neler çalışıyor, neler planlı

Çalışıyor bugünkü kodda ve canlıda Faz N planlı, ilgili fazda gelir MVP dışı sonraya bırakıldı

Bugün çalışan Çalışıyor

  • macOS, Windows ve Linux masaüstü paketleri; portaldan PC enrollment ve revoke.
  • Chat UI (OpenCode fork) ve PC'de opentagd: Kubernetes, SSH, PostgreSQL, HTTP API, SMTP, script ve Ansible tool'ları.
  • Zorunlu plan, k8s ve SQL için preview, secret masking, guard plugin, local audit log.
  • Platform: Postgres ve RLS, Zitadel role'leri, agent enrollment (pc ve site), WSS gateway, job queue, LLM proxy, skill repo.
  • Server agent: opentagd install --server (systemd, Windows service, Docker image).
  • PC'deki AI, server agent'taki bir connection'da tool'u platform job'ı olarak çalıştırır; connection'lar birleşik listede görünür.

Planlı Faz 2-4

  • Faz 2: policy, console'da onay, imzalı tek kullanımlık approval ticket, agent'ta local allowlist, age secret store ve recovery key, console'dan şifreli secret girişi, PowerShell tool'ları.
  • Faz 3: console relay (tarayıcı 127.0.0.1'e gitmez), console'da chat, skill kartlarından oluşan Katalog sayfası, MCP repo ve aggregator, üyeler ve davet, LiteLLM limitleri.
  • Faz 4: scheduled job'lar ve standing approval, platformda audit summary, Google, n8n ve merkezi entegrasyon kodunun kaldırılması, failure testleri, pilot kurulum belgesi.
  • MVP dışı ürüne özel entegrasyonlar, template/workflow engine, platformun müşteri sunucusuna kurulumu, OpenBao ve kısa ömürlü SSH sertifikası, code signing ve auto-update, SIEM ve SCIM, merkezi sohbet arşivi.

Geçiş dönemi notu: Google hesabı bağlama ve n8n akışları ilk sürümden kalmadır ve bugün kodda durur. Generic core kararıyla (15 Ekim) bırakıldı; Faz 4'te kaldırılır (issue #44-#48).

04 · Mimari

Üç parça: platform, PC agent, server agent

Platform bizim sunucumuzda, multi-tenant çalışır. Her agent platforma outbound tek bir WSS connection (443) açar; şirkette port açmak ya da VPN kurmak gerekmez. Job'ı, connection'ın durduğu agent çalıştırır.

OpenTAG mimarisi Tarayıcı IT çalışanı · şirket admini portal · console · chat UI Platform · bizim sunucumuz · k3s Portal / console Next.js 16 · next-auth (OIDC) opentag.nesiler.com Chat UI OpenCode web, statik chat.opentag.nesiler.com Platform API · Go api.opentag.nesiler.com Auth ve role'ler Zitadel JWT · tenant Agent'lar pc · site · enrollment WSS gateway /v1/agent/connect Job queue jobs · lease · ACK LLM proxy SSE, buffer'sız Skill repo central · shared Faz 2-4: policy · ticket · relay · MCP · scheduler · audit Postgres 16 RLS · goose günlük backup Zitadel OIDC · org = tenant project role'leri LiteLLM kullanıcı başına virtual key Faz 3: tenant bütçesi, TPM/RPM LLM provider bugün DeepSeek (flash · pro) Şirket · port açılmaz, VPN gerekmez PC agent · IT çalışanının bilgisayarı opentagd · yalnız 127.0.0.1:4747 OpenCode (fork) · tek MCP endpoint secret'lar: Keychain / Credential Manager macOS · Windows · Linux Server agent · sürekli açık makine opentagd --server · yerel port yok systemd · Windows service · Docker shared connection'lar ve secret'lar Faz 2: age store, local allowlist Şirket sistemleri Linux (SSH, Ansible) · Kubernetes PostgreSQL · HTTP API · SMTP Faz 2: Windows (PowerShell) Faz 3: external MCP server'lar HTTPS server tarafı Zitadel token JWKS /llm WSS 443 + HTTPS: LLM, job'lar device token WSS 443 outbound kişisel connection'lar: PC agent doğrudan bugün: tarayıcı → 127.0.0.1:4747 (local token) Faz 3: console relay ile bu yol kalkar
Düz çizgi: bugün çalışan. Sarı ve kesikli: planlı ya da kalkacak. LLM çağrısı zinciri: OpenCode → 127.0.0.1:4747/llm/v1/* → platform /v1/llm/v1/* (device token) → LiteLLM (kullanıcının virtual key'i).

İlkeler

  • Connection'ı her zaman agent açar. WSS connection üç şey taşır: job queue, console relay (Faz 3) ve config değişikliği bildirimleri.
  • Queue Postgres'te. Lease, ACK ve redelivery; sonucu belirsiz kalan write job tekrarlanmaz.
  • AI her zaman PC'deki OpenCode'dan çağırır. Hedef connection server agent'taysa çağrı platform üzerinden job olarak oraya gider.
  • Single-tenant kurulum engellenmez. Aynı image, config env'den, her tabloda tenant_id. Müşteri sunucusuna kurulum MVP sonrasıdır.

05 · Bileşenler

Her bileşen: görev, teknoloji, veri, arayüz

Platform

platform/ · Go

Go (stdlib net/http) tek servis, api.opentag.nesiler.com. k3s'te opentag-backend namespace'i, tek replica.

  • Zitadel JWT doğrulama (JWKS, iss, aud); tenant = Zitadel org id, ilk görüldüğünde oluşur. Client'tan gelen tenant bilgisine güvenilmez.
  • Enrollment kodu (10 dk, tek kullanım), device token (90 gün, DB'de sha256), local access token (Ed25519 JWT, 12 saat) ve /.well-known/jwks.json.
  • Agent'lar (kind=pc|site), kurulum token'ı, WSS gateway, jobs queue (agent başına aynı anda en çok 8 job).
  • LLM proxy: LiteLLM'e buffer'sız reverse proxy; kullanıcı başına virtual key ilk çağrıda üretilir ve izinli modellerle sınırlıdır. LiteLLM master key yalnız platformdadır.
  • Skill repo (central ve shared, integer version, ≤ 256 KB, secret pattern taraması).
  • Log'a yalnız method, path, status ve süre yazılır; token, kod ya da anahtar yazılmaz.
  • Faz 2-4 policy, onaylar ve ticket imzalama, shared connection endpoint'leri, relay, MCP repo, üyeler, limitler, scheduler, audit summary.

Postgres

postgres:16-alpine
  • Tek instance, 10 Gi persistent volume; her gece 02:30'da pg_dump CronJob'u (ayrı 5 Gi backup volume'u). Restore denemesi Faz 4'te (4.7).
  • goose migration'ları startup'ta uygulanır (00001_init, 00002_agents, 00003_jobs). SQLite'tan geçildi; yalnız Postgres desteklenir.
  • Tenant izolasyonu RLS ile: tablolar ENABLE + FORCE ROW LEVEL SECURITY, policy tenant_id = app_tenant(); her DB connection'ında SET app.tenant_id.
  • Backend superuser değildir: opentag_app role'ü (BYPASSRLS yok). Superuser yalnız yönetim ve backup içindir.

Portal ve console

portal/ · Next.js
  • Next.js 16 (App Router), React 19, Tailwind 4, next-auth 5 (Zitadel OIDC, PKCE). opentag.nesiler.com.
  • Backend çağrıları yalnız server tarafında; Zitadel token'ı tarayıcıya verilmez.
  • Bugünkü sayfalar: tanıtım, genel bakış (indirme, eşleştirme, cihazlar), Ajanlar (kurulum token'ı, online durumu), bağlantılar, skill'ler, entegrasyonlar (Faz 4'te kalkar).
  • Faz 3 console: AI SDK useChat ve relay üzerinden çalışan kendi OpenCode transport'u, AI Elements, streamdown; JSON Schema'dan formlar (react-hook-form + Ajv); next-intl. Ekranlar: starter kartları, chat ve onay kartı, onay bekleyenler, agent'lar, connection'lar ve secret girişi, skill'ler, MCP server'lar, scheduled job'lar, üyeler, policy, usage, audit.

PC agent

agent/ · opentagd
  • Tek Go binary'si; PC modunda yalnız 127.0.0.1:4747'de dinler. Host loopback değilse ve Origin izinli değilse 403 (DNS rebinding koruması).
  • OpenCode'u başlatır, çökerse 5 dakikada en çok 5 kez yeniden başlatır. OpenCode'a her başlatmada rastgele üretilen OPENTAG_LLM_KEY, OPENTAG_MCP_KEY ve iç parola verir.
  • /mcp: MCP server (Streamable HTTP). Bütün tool'lar burada; çıktı 20 KB'a kesilir, secret'lar maskelenir, her çağrı audit.log'a yazılır.
  • Connection'lar: secret olmayan alanlar connections.yaml'da, secret'lar Keychain / Credential Manager'da (uzun değerler 1000 baytlık parçalara bölünür).
  • Tool routing: başka agent'taki connection'da her tool, kişisel connection'da yalnız write tool'lar platform job'ı olur.
  • Heartbeat 60 sn; platform 401 device_revoked derse token silinir ve bütün endpoint'ler 403 döner.

Server agent

opentagd --server
  • Aynı binary, server modunda: OpenCode başlatılmaz, yerel port açılmaz. Veri dizini /var/lib/opentag ya da %ProgramData%\OpenTag.
  • opentagd install --server --token <ota_…>: enrollment, device token'ı 0600 dosyaya, Linux'ta systemd system service, Windows'ta otomatik başlayan service. Docker image da var (OPENTAG_ENROLL_TOKEN).
  • Linux paketinde ansible ve uv bulunur; Windows server agent'ta Ansible tool'ları yoktur.
  • Biten job'lar jobs-done.json'da (son 200) tutulur; aynı job_id gelirse tool yeniden çalışmaz.
  • Bugün secret girişi sunucuda opentagd secret set ile (stdin'den, 0600 dosya). Faz 2 age ile şifreli secret store, key Windows'ta DPAPI'de, Linux'ta root'a ait 0600 dosyada; recovery key, console'dan şifreli giriş.

OpenCode client

client/ · OpenCode fork
  • OpenCode v2.0.20'nin MIT lisanslı fork'u: runtime ve web UI. Marka, sabit backend adresi, varsayılan proje ~/opentag/work; terminal (PTY) ve upstream'e giden dış bağlantılar kaldırıldı.
  • Agent'lar: opentag (ana, deepseek-flash-deepseek) ve uzman (read-only subagent, deepseek-pro-deepseek). Yerleşik build / plan kapalı, yalnız opentag provider'ı etkin.
  • Guard plugin (opentag-guard.js): bash yasakları, argümanlarda düz secret engeli, sohbete inventory ve connection özeti.
  • Paketle gelen skill'ler ve system prompt Türkçe.

Zitadel

identity

OIDC provider. Her müşteri bir org'dur; role'ler project role'leridir ve JWT'deki urn:zitadel:iam:org:project:<id>:roles claim'inden okunur. Access token RS256, 12 saat. Faz 3 davet, role değiştirme, disable etme ve tenant açma script'i.

LiteLLM

ai.nesiler.com

Model erişim katmanı. Bugün kullanıcı başına virtual key (opentag:<email>), izinli modeller deepseek-flash-deepseek ve deepseek-pro-deepseek. Faz 3 şirket = LiteLLM team (bütçe, TPM/RPM, izinli modeller), kullanıcı bütçesi, limit aşımında 429 llm_limit_exceeded. Kişisel veri maskeleme ayrı llm-gateway projesinde (LiteLLM + Presidio) paralel yürür.

Ansible

ansible/ · catalog.yml

Linux bakım ve hardening playbook'ları ve catalog'u. macOS ve Linux paketine collection'lar ve role'ler önceden kurulu girer; çalışma anında Galaxy'ye gidilmez. ansible-core 2.21.4 paketteki uv ile pinned version'da çalışır. Ayrıntı: Tool'lar, skill, MCP.

06 · Veri nerede durur

Şirkette kalan, platforma gelen

VeriNeredeDurum
Kişisel secret'larPC agent'ta: bugün OS keystore'unda (Keychain, Credential Manager, Secret Service); Faz 2'de key'i OS keystore'unda duran age dosyasıÇalışıyor
Paylaşılan secret'larServer agent'ta: bugün 0600 dosya; Faz 2'de age ile şifreli dosya. Platform yalnız adını bilirFaz 2 store
Sohbet geçmişi, ham komut çıktılarıAgent'larda (PC'de OpenCode session'ları, agent'ın audit.log'u ve runs/ dizini)Çalışıyor
Route edilen job'ın argümanı ve sonucuPlatformda jobs tablosunda; sonuç agent'ta maskelenmiş ve 20 KB'a kesilmiş olarak gelir. Argümanda yerel secret değeri varsa job açılmaz (secret_in_args)Çalışıyor
Kullanıcı, role, agent, skill, job durumuPlatformda, tenant'a bağlı (RLS)Çalışıyor
MCP tanımı, policy, onay, audit summaryPlatformda; audit yalnız özet: kim, hangi tool, hangi connection, karar, sonuç, çıktının sha256'sıFaz 2-4
LLM'e giden içerikLiteLLM üzerinden provider'a gider; secret değerleri tool çıktısında maskelenmiştir. Platform içeriği saklamaz ve log'a yazmazÇalışıyor
Relay trafiğiPlatform iletir, hiçbir yere yazmazFaz 3

07 · Arayüzler

Platform API, WSS protokolü, MCP tool'ları

Contract docs/api.md'dedir; §7 MVP contract'ıdır (v1). Body'ler JSON, hata biçimi {"error": {"code", "message"}}.

Auth türleri

AdHeaderKim kullanır
ZitadelBearer <Zitadel access token>Portal (yalnız server tarafı)
DeviceBearer otd_…opentagd (PC ve server agent), HTTPS ve WSS
LocalBasic opencode:<jwt> ya da Bearer <jwt>Tarayıcı → PC'deki opentagd (Faz 3'te relay ile kalkar)
AdminBearer <OPENTAG_ADMIN_TOKEN>Admin script'i (central skill upload)

Platform endpoint'leri

EndpointAuthNe yaparDurum
POST /v1/enrollments, POST /v1/devices/enrollZitadel / kodPC enrollment: XXXX-XXXX-XXXX kodu → device tokenÇalışıyor
POST /v1/local-tokens, GET /.well-known/jwks.jsonZitadel / yokTarayıcının opentagd'ye gittiği 12 saatlik EdDSA token ve public keyÇalışıyor
POST /v1/devices/heartbeatDevicelast_seen_at, skills_versionÇalışıyor
POST /v1/agent-tokens, POST /v1/agents/enrollsirket_admini / tokenServer agent kurulum token'ı (ota_, 24 saat, tek kullanım) ve enrollmentÇalışıyor
GET /v1/agents, DELETE /v1/agents/{id}ZitadelAgent listesi ve online durumu; revoke açık WSS connection'ı kapatırÇalışıyor
GET /v1/connectionsDeviceTenant'ın server agent'larındaki shared connection'lar (secret değeri yok)Çalışıyor
GET /v1/agent/connectDeviceWSS, subprotocol opentag.v1Çalışıyor
POST /v1/jobs, GET /v1/jobs/{id}?wait=, POST /v1/jobs/{id}/cancelDevice / ZitadelJob oluşturma, long-poll (en çok 120 sn), cancelÇalışıyor
ANY /v1/llm/*DeviceLiteLLM'e buffer'sız reverse proxy (SSE)Çalışıyor
/v1/skills*, /v1/admin/skills/*Zitadel / Device / AdminListe, içerik, manifest, bundle, paylaşım, central uploadÇalışıyor
GET/PUT /v1/policy, GET /v1/approvals, POST /v1/approvals/{id}ZitadelPolicy ve onay; approval endpoint'i yalnız kullanıcı session'ıylaFaz 2
PUT /v1/agents/{id}/connections/{type}/{name} (+ /grants), PUT /v1/agents/{id}/secrets/{name}sirket_adminiShared connection ve tarayıcıda age ile şifrelenmiş secret girişiFaz 2
/v1/relay/{agent_id}/*Zitadel (sahibi)Console'dan PC agent'a relay; path allowlistFaz 3
/v1/mcp-servers, /v1/members, /v1/invites, /v1/usage, /v1/admin/tenants/{id}/limitsZitadel / AdminMCP repo, üyeler, davet, usage, limitlerFaz 3
/v1/schedules, GET /v1/auditZitadel / DeviceScheduled job'lar, audit summaryFaz 4

WSS agent protokolü (opentag.v1)

Her mesaj tek bir JSON frame'dir: {"type": "...", "id": "<ulid>", ...}; bilinmeyen type ignore edilir. Agent 25 sn'de bir ping gönderir; 60 sn sessiz kalan agent offline sayılır, connection'ı kopan agent hemen offline olur. Reconnect 1 sn'den 60 sn'ye kadar artan, jitter'lı backoff ile. Aynı agent yeniden bağlanırsa eski connection kapatılır.

YöntypeAlanlarDurum
A→Phelloagent_id, kind, version, os, tools[], connections[], mcp_servers[], age_recipient (secret değeri yok)Çalışıyor
P→Awelcometenant_id, config_version, ticket_jwks, heartbeat_sÇalışıyor
↔ping / pong—Çalışıyor
A→Pinventory.changedconnections, mcp_serversÇalışıyor
P→Ajob.offerjob_id, attempt, lease_s, tool, connection?, args, ticket?, idempotency_key, deadlineÇalışıyor (ticket Faz 2)
A→Pjob.ack / job.leasejob_id, attempt; lease'i 30 sn uzatırÇalışıyor
A→Pjob.resultjob_id, attempt, ok, result, error?, output_sha256, started_at, finished_atÇalışıyor
P→Ajob.canceljob_idÇalışıyor
A→Pjob.progressjob_id, seq, text (maskeli)platform kabul eder; agent henüz göndermez
P→Aconfig.changedskills_version, mcp_version, policy_versionFaz 3
P→A / A→Psecret.put / secret.acktarayıcıda şifrelenmiş secrets_age, connection testi sonucuFaz 2
↔relay.open / head / data / closestream_id, method, path, headers, body; base64 chunk'larFaz 3
A→Paudit.batchyerelde çalışan okumaların özeti; offline iken biriktirilirFaz 4

Önemli hata kodları

KodHTTPAnlam
device_revoked401Cihaz revoke edilmiş; agent token'ı siler
enrollment_used / _expired / _invalid409 / 410 / 400Enrollment kodu ya da kurulum token'ı kullanılmış, süresi dolmuş ya da bilinmiyor
agent_offline409Connection'ın agent'ı offline ve son 2 dk içinde görülmedi
connection_not_found / job_not_found404Bilinmeyen agent ya da başka tenant'ın job'ı
plan_required, secret_in_args, secret_host_mismatchtool hatasıWrite tool'da plan eksik; argümanda yerel secret; secret yanlış host'a gidecekti
pending_approval, denied, ticket_invalid, capability_disabled202 / 403Faz 2 onay ve policy
llm_limit_exceeded, requires_server429 / 412Faz 3-4 LLM limiti; server agent yok

PC'deki opentagd'nin yerel API'si (/opentag/*, /llm/v1/*, /mcp) ve tool listesi docs/api.md §2-§3'tedir; tool'ların özeti Tool'lar, skill, MCP bölümünde.

08 · Akışlar

Temel akışlar, sequence diagram'larıyla

Düz ok istek, kesikli ok yanıt. Diyagramlar dar ekranda yatay kaydırılır.

1. PC agent enrollment Çalışıyor

PC agent enrollmentTarayıcıPortal (Next.js)Platform APIopentagd (PC)Zitadel ile giriş (OIDC, PKCE)POST /v1/enrollments · Zitadel JWT{code: XXXX-XXXX-XXXX} · 10 dk, tek kullanımenrollment koduPOST 127.0.0.1:4747/opentag/enroll {code}yalnız enroll edilmemişken · izinli Origin · loopback HostPOST /v1/devices/enroll {code, device_name, os}{device_id, device_token: otd_…, tenant_id}device token → Keychain / Credential ManagerWSS /v1/agent/connect · hellowelcome {tenant_id, config_version, heartbeat_s}
Kod 10 dk geçerli ve tek kullanımlıktır. Device token opaque, 90 gün geçerli, platformda yalnız sha256'sı durur; portaldan revoke edilir.

2. Server agent kurulumu Çalışıyor

Server agent kurulumuŞirket adminiPortal (Ajanlar)Platform APIopentagd --serverAjanlar sayfası: kurulum token'ı üretPOST /v1/agent-tokens {name} · role: sirket_admini{token: ota_…, expires_at} · 24 saat, tek kullanımopentagd install --server --token ota_…POST /v1/agents/enroll {token, name, os, age_recipient}{agent_id, device_token, tenant_id}token 0600 dosyaya · systemd / Windows service kurulurWSS hello {tools, connections (secret değeri yok)}welcomeGET /v1/agents → online: true
Kurulum token'ı yalnız sirket_admini rolüyle alınır (it role'ü 403). Kullanılmış token 409, süresi dolmuş 410 döner. Agent portalın aynı Ajanlar sayfasında online görünür.

3. Sohbet → MCP tool → platform job → server agent Çalışıyor

Sohbet → MCP tool → platform job → server agentOpenCode (PC)opentagd (PC)PlatformPostgresopentagd --serverHedef sistemPOST /mcp ssh_read {conn: <agent>/ssh/web-01}connection başka agent'ta → job olarak gönderPOST /v1/jobs {tool, connection, args}INSERT jobs (status=queued, RLS){job_id, status: queued}GET /v1/jobs/{id}?wait=50WSS job.offer {job_id, attempt, lease_s: 30, …}job.ackSSH: df -h (secret agent'ta çözülür)çıktımasking · 20 KB limit · audit.logjob.result {ok, result, output_sha256}UPDATE jobs status=done{status: done, result}tool sonucu
Connection id'si <agent_id>/<type>/<name>; job ilk parçadaki agent'a gider. Kişisel connection'da read tool'lar platforma uğramadan local çalışır; kişisel write job'lar da platform job'ı olur ve aynı PC'ye geri döner (Faz 2'de ticket bu yoldan gelir). PC tarafı sonucu toplam en çok 10 dk bekler.

4. Lease, redelivery ve idempotency Çalışıyor

Lease, redelivery ve idempotencyPlatformPostgres (jobs)AgentUPDATE … FOR UPDATE SKIP LOCKED → running, attempt+1job.offer {attempt: 1, lease_s: 30}Agent ack göndermeden koparsa ya da lease dolarsastatus=queued (read veya write)job.offer {attempt: 2} · reconnect oluncaNormal akışjob.ack → lease +30 snjob.lease · her 15 sn (lease_s/2)job.resultack'ten sonra kopmaread job → queued · write job → unknownunknown kendiliğinden yeniden çalıştırılmazAynı job tekrar gelirsejob.offer {job_id aynı}jobs-done.json: tool yeniden çalışmazjob.result (saklanan sonuç)Deadlinequeue'da 10 dk → failed (deadline_exceeded)
Platform 2 sn'de bir lease'i dolan job'ları tarar. Write sınıfı: write tool'lar ve bilinmeyen tool'lar. unknown job için geç gelen sonuç da kabul edilir. PC tarafında yarıda kesilen çağrı için cancel istenir; cancel doğrulanamazsa AI'a canceled_unconfirmed döner ve yazmayı tekrarlamadan önce durumu read tool ile kontrol etmesi söylenir.

5. Skill sync Çalışıyor

Skill syncIT çalışanı (opentagd)Platform APIPostgresDiğer PC agent'larıPOST /v1/skills {name, files} · paylaşsecret pattern taraması · ≤ 256 KBskills: tenant içinde, version+1{name, version}POST /v1/devices/heartbeat · 60 sn{ok, skills_version}version değişti mi?GET /v1/skills/bundle{version, skills: central + shared}temp dizine yaz → rename
Skill'ler <data dir>/skills/{central,shared}/ altına yazılır ve OpenCode'a OPENTAG_SKILLS_DIR ile verilir; geçersiz path içeren bundle tümüyle reddedilir. Faz 3 config.changed ile değişiklik 1 dk içinde agent'a ulaşır.

Planlı akışlar

AkışÖzetFaz
Onaylı writePOST /v1/jobs → policy ask/approval → console'da onay kartı → platform ticket'ı imzalar → job.offer {ticket} → agent ticket'ı ve local allowlist'i doğrular → çalışırFaz 2
Console'dan secret girişiTarayıcı değeri agent'ın age_recipient key'ine şifreler → platform yalnız iletir (secret.put) → agent açar, connection'ı test eder → secret.ackFaz 2
Console relayConsole /v1/relay/{agent_id}/* → relay.open WSS üzerinden PC agent'a → local OpenCode; SSE stream'leri de bu yoldan, içerik yazılmazFaz 3
Scheduled jobAI schedule_create önerir → standing approval → platform zamanı gelince job'ı server agent'a yollar → sonuç console'daFaz 4

09 · Güvenlik modeli

Secret değerleri modele hiçbir zaman ulaşmaz

Tenant izolasyonu Çalışıyor

  • Tenant = Zitadel org id; token'dan gelir, client'ın söylediği tenant'a güvenilmez.
  • Postgres RLS: her tabloda tenant_id, FORCE ROW LEVEL SECURITY, DB connection başına app.tenant_id. Her sorgu scope'unu connection'a yazarak çalışır; scope'u yazılmamış connection hiçbir satır görmez. Tenant'sız scope yalnız authentication, enrollment, admin ve lease taraması gibi server-side yollardadır.
  • Backend RLS'i atlayamayan bir role ile bağlanır (opentag_app, BYPASSRLS yok).
  • Faz 1 kabulünde ikinci bir tenant'ın kullanıcısı agent'ı, connection'ı ve job'ı göremedi: listeler boş, job/cancel/delete/connection endpoint'leri 404.

Kimlikler ve token'lar

TokenÜreten → doğrulayanÖmürDurum
Zitadel access token (JWT, RS256)Zitadel → platform (JWKS, iss, aud)12 saatÇalışıyor
Enrollment kodu XXXX-XXXX-XXXXPlatform → platform10 dk, tek kullanımÇalışıyor
Kurulum token'ı ota_Platform → platform24 saat, tek kullanımÇalışıyor
Device token otd_ (opaque)Platform → platform (DB'de sha256)90 gün, revoke edilebilirÇalışıyor
Local access token (JWT, EdDSA)Platform → opentagd (platform JWKS)12 saatÇalışıyor
OpenCode iç parolası, OPENTAG_LLM_KEY, OPENTAG_MCP_KEYopentagd → opentagd / OpenCodeprocess ömrü, her başlatmada rastgeleÇalışıyor
LiteLLM virtual keyPlatform (kullanıcı başına) → LiteLLMsüresiz; master key kullanıcıya gitmezÇalışıyor
Approval ticket (JWS, EdDSA)Platform → agent (ticket_jwks)en çok 10 dk, tek kullanımFaz 2

Komut ve pty process'lerinin environment'ından bu key'ler temizlenir; AI'ın çalıştırdığı child process'ler bu key'leri görmez.

Agent ve client katmanları Çalışıyor

KatmanNasıl
Form ile girişCredential'lar sohbete yazılmaz; model request_connection / request_secret ile portal formunun linkini verir.
secret:// referansıModel yalnız secret://<type>/<name>/<field> görür; referans yalnız opentagd içinde çözülür.
Secret-host bindingHTTP tool'larında {{secret://…}} yalnız o connection'ın secret'ı ya da hosts listesi hedefi içeren secret için çözülür; aksi halde secret_host_mismatch. Başka host'a ya da https→http'ye redirect takip edilmez.
MaskingBütün connection'ların secret'ları bütün tool çıktılarında ve hatalarda *** olur: düz, JSON, URL-kaçışlı, Python repr, base64, hex. 8 karakterden kısa değerler maskelenmez. Kubernetes Secret değerleri hiç gösterilmez.
Değeri dışarı vermeyen tool'lark8s_compare_secret_keys yalnız eşit/değil döner; k8s_copy_secret_key ve k8s_set_secret_key değeri opentagd içinde taşır.
Plan ve previewBütün write tool'lar plan: {hedef, etki, geri_alma, dogrulama} ister. preview_change k8s için dry-run diff, sql_exec için rollback'li çalıştırma yapar.
Read-only SSHssh_read yalnız allowlist'teki komutları kabul eder; ;, &&, >, $(, sudo reddedilir. Bir filtredir, security boundary değildir.
Dosya izinleri.env, *.pem, *.key, ~/.ssh, ~/.kube, ~/.aws, Keychain'ler ve OpenTAG kurulum dizini OpenCode'da deny.
NetworkPC'de yalnız 127.0.0.1; Host loopback değilse ya da Origin izinli değilse 403. Server agent hiç port açmaz.
SSH host keyİlk bağlantıda pin'lenir (TOFU); sonradan değişirse connection reddedilir.
Local auditHer MCP çağrısı audit.log'a JSON satırı (zaman, tool, connection, maskeli parametreler, sonuç); 5 MB'ta rotate edilir.

Guard plugin

Guard kullanıcıya yönelik bir filtredir; security boundary Faz 2'de ticket ve agent'ın local allowlist'idir. Bash komutu ;, &&, ||, |, $( ), backtick ve sh -c ile bölünür, her parça ayrı kontrol edilir.

  • Yasaklar: tehlikeli rm -rf hedefleri, sudo/su/doas, dd of=, mkfs, chmod -R 777, indirip çalıştırma (curl … | sh), git push --force, shutdown/reboot, OpenTAG process'lerini kill etme, env/printenv ve secret dizinleri.
  • Bütün tool argümanlarında düz secret pattern'leri (-----BEGIN, JWT, AKIA, ghp_, sk-, xox[bp]-) engellenir; model request_secret'a yönlendirilir.

Planlı katmanlar

KonuNe gelirFaz
Onay ve ticketWrite job yalnız imzalı, tek kullanımlık, 10 dk'lık ticket ile çalışır; agent'ta local allowlist. Ayrıntı: Onay ve policy.Faz 2
Secret storeage ile şifreli dosya; key DPAPI / root'a ait 0600 dosya / Keychain. Kurulumda bir kez gösterilen recovery key; opentagd secret backup / restore. Sunucuda root'un store'a erişebilmesi bilinçli olarak kabul edildi.Faz 2
OffboardingDisable edilen kullanıcının cihazları ve LiteLLM key'i hemen revoke edilir. Bugün cihaz revoke'u portaldan tek tek yapılır.Faz 3
Audit summaryPlatformda yalnız özet (kim, tool, connection, karar, sonuç, çıktı sha256'sı); komut çıktısı ve sohbet agent'ta kalır.Faz 4
Failure testleriNetwork kopması, job ortasında ölen agent, platform restart'ı, ticket replay, süresi dolmuş ticket, yanlış tenant, recovery key ile geri dönüş.Faz 4

10 · Onay ve policy

Onay platformda verilir, agent'ta doğrulanır

Bugün: write tool'lar plan ister ve OpenCode'un permission prompt'unda parametreleriyle kullanıcı onayına düşer (opentag_*: ask). Platform tarafında policy her job'a allow der ve ticket yoktur. Faz 2 ile aşağıdaki model devreye girer ve OpenCode prompt'u opentag tool'larında kapanır; tek onay yeri console'daki onay kartı olur.

Policy Faz 2

Karar şu girdilere bakar: tool, read/write sınıfı, risk, connection label'ı (ör. env=prod) ve role. Kurallar çakışırsa en sıkı karar kazanır.

RiskVarsayılan
none (read)allow: onay sorulmaz
medium (write)ask: isteyen kullanıcı console'da onaylar
high (run_with_connection, ansible_run)ask; şirket approval yapabilir (başka kullanıcı onaylar)
criticaldeny

Şirket, role bazında hangi capability'lerin açık olduğunu seçer; kapalıysa capability_disabled. Self-approval engellenir.

Approval ticket Faz 2

{"iss": "opentag-platform", "tid": "<tenant>",
 "aid": "<agent_id>", "jti": "<job_id>",
 "tool": "ssh_run", "conn": "<agent_id>/ssh/web-01",
 "args_sha256": "<sha256(JCS(args))>",
 "decision": "allow|ask|approval|standing",
 "approved_by": ["<sub>"], "schedule_id": null,
 "iat": 0, "exp": 0}

JWS (EdDSA / Ed25519). Argümanlar RFC 8785 (JCS) ile canonicalize edilip hash'lenir; ticket tool'a, connection'a ve argümanların hash'ine bağlıdır.

Agent write tool'u çalıştırmadan önce

  1. İmzayı doğrular (welcome.ticket_jwks, use: ticket).
  2. tid, aid, jti, tool, conn, args_sha256 alanlarını job'ın kendisiyle karşılaştırır.
  3. Süreyi (exp) kontrol eder.
  4. jti'nin kullanılmadığını kontrol eder ve diske yazar.
  5. Local allowlist'i (policy.yaml; sunucuda root'a ait, 0600, platform değiştiremez) uygular.

Biri tutmazsa ticket_invalid. Approval endpoint'i yalnız Zitadel session'ıyla çağrılır; device token ve MCP key 401 alır, bu yüzden AI kendi job'ını onaylayamaz. Local allowlist bizim sunucumuz ele geçirilse bile geçerlidir.

Standing approval Faz 4

Scheduled job = sabit argümanlı tek bir tool çağrısı ({tool, connection, args, cron, tz}). Standing approval tool + conn + args_sha256'ya bağlıdır, biri değişirse düşer; en çok 90 gün, yalnız risk ≤ medium. Yalnız server agent'ta çalışır; yoksa requires_server.

11 · Tool'lar, skill, MCP

Capability, skill ve MCP server

Core hiçbir ürüne özel kod içermez. Capability: opentagd'nin generic tool'ları. Skill: bilgi ve yöntem (Agent Skills biçimi). MCP server: dışarıdan eklenen tool seti.

Capability'ler

CapabilityTool'larConnection typeDurum
linuxssh_read, ssh_run, ansible_search, ansible_check, ansible_runsshÇalışıyor
kubernetesk8s_get|describe|logs|events, k8s_rollout_restart|scale|delete_pod|set_env|trigger_cronjob, k8s_compare|copy|set_secret_keykubernetesÇalışıyor
databasesql_query (READ ONLY, tek ifade, ≤ 200 satır, 30 sn), sql_execpostgresÇalışıyor
httphttp_get, http_requesthttp_apiÇalışıyor
scriptrun_with_connection (python / shell, izole çalışma dizini, 60-300 sn)herhangiÇalışıyor
mailsmtp_sendsmtpÇalışıyor
windowspowershell_read, powershell_run (Windows'un OpenSSH'ı, -EncodedCommand)ssh (shell: powershell)Faz 2
  • Yardımcı tool'lar: list_connections, request_connection, request_secret, test_connection, define_connection_type, preview_change.
  • Connection type'ları generic'tir: ssh, kubernetes, postgres, http_api, smtp, secret ve AI'ın tanımladığı type'lar (kullanıcı onaylamadan kullanılamaz). Örneğin Proxmox bir http_api connection'ıdır.
  • Sınıf ve risk: read none, write medium, run_with_connection ve ansible_run high. Tablonun koda ve MCP annotation'larına geçmesi Faz 2 (2.1).

Skill'ler Çalışıyor

disk-doldu/
├── SKILL.md
├── references/*.md
└── scripts/*.sh | *.ps1 | *.py
  • Kaynaklar: central (biz), shared (yalnız o şirket), local (kullanıcının bilgisayarı).
  • Paketle gelenler: ansible, kubernetes, linux-ssh, caddy, headscale, postgres, mail, secrets, runtime, baglanti-tipi-yazma, onboarding, skill-yazma.
  • AI çözdüğü sorunu skill olarak yazar; kullanıcı şirketle paylaşır. Skill içeriği yalnız talimattır, tool'ların onay kurallarını değiştiremez.

Faz 3 skill frontmatter'ındaki metadata starter kartlarını ve Katalog'u üretir; template engine yoktur, rehberli iş skill'dir.

---
name: disk-doldu
description: Linux sunucuda disk dolduğunda ...
metadata:
  opentag.requires: linux
  opentag.category: linux
  opentag.card: Diski dolan sunucuda yer açar
  opentag.starter: "Sunucumun diski doldu, yardım eder misin?"
  opentag.audience: beginner
---

Pilot skill'leri disk-doldu, ad-parola ve rehberler linux-temel, windows-temel Faz 3'te (3.9).

MCP repo Faz 3

{"name": "proxmox", "transport": "stdio",
 "command": ["uvx", "proxmox-mcp@1.2.0"],
 "env": {"PROXMOX_TOKEN": "secret://site/proxmox-token"},
 "runs_on": "site",
 "tools": {"default": "write",
           "overrides": {"get_vms": "read"}}}
  • Şirket console'dan external MCP server ekler: stdio (pinned version uvx/npx) ya da http.
  • MCP server agent'ta çalışır: runs_on: site shared secret'larla, runs_on: pc kişisel secret'larla.
  • opentagd hepsini kendi tek MCP endpoint'inin arkasında toplar (mcp_<server>_<tool>); onay, audit ve masking her tool'da aynıdır.
  • readOnlyHint'a güvenilmez: sınıf varsayılan write, console'da tek tek read işaretlenir.

Ansible catalog'u Çalışıyor

Yalnız catalog.yml'deki playbook'lar çalışır; vars catalog tanımına göre doğrulanır. Akış: ansible_search → ansible_check (write playbook'u --check --diff) → onay → ansible_run → audit'i yeniden çalıştırıp karşılaştırma. macOS, Linux ve Linux server agent'ta sunulur.

PlaybookModNe yapar
cis_auditreadCIS Ubuntu 24.04 compliance audit'i; başarısız kontrolleri raporlar, düzeltme yapmaz
ssh_hardeningwriteRoot ve parola girişi kapalı, güçlü algoritmalar, deneme sınırı; anahtarla giriş açık kalır
os_hardeningwriteKernel ayarları, parola kuralları, dosya izinleri, auditd
firewall_ufwwriteGelen trafik kapalı; SSH ve izin verilen portlar açık
fail2banwriteDeneme saldırısı yapan IP'leri geçici engeller
package_updatewriteBekleyen paket güncellemelerini uygular

12 · Katalog

Katalog: IT çalışanı ne yazacağını bilmeden işe başlar

Console'a Katalog sayfası gelir Faz 3. Her kart bir skill'dir: kart metni, kategori ve starter cümlesi skill'in metadata alanından gelir. Karta tıklamak sohbeti başlatır; iş yine sohbetin içinde, AI'ın skill'i izlemesiyle yürür. Ayrı bir form ya da template engine yoktur.

Tasarım mock'u Faz 3 console sayfası (#34, #30) · bugünkü portalda yok · içerik örnektir
opentag.nesiler.com/katalog

Katalog

Şirketinizin skill'lerinden hazır işler. Bir kart seçin, sohbet onunla başlar.

Tümü · 8Başlangıç · 5Linux · 2Windows / AD · 1Kubernetes · 1Mail · 1Network / VPN · 1Güvenlik / Uyum · 2

Linux

Disk dolducentral

Diski dolan sunucuda yer açar: neyin yer kapladığını bulur, seçtiğiniz temizliği onayla yapar.

başlangıçlinuxdisk-doldu
Chat'te başlat →
Bakım penceresinde paket güncellemeshared

Bekleyen güncellemeleri listeler, şirketin bakım kuralıyla package_update playbook'unu çalıştırır.

ilerilinuxbakim-guncelleme
Chat'te başlat →

Windows / AD

AD parola sıfırlamacentral

Kullanıcıyı bulur, parolasını sıfırlar ya da hesap kilidini açar; değişiklik onay kartından geçer.

başlangıçwindowsad-parola
Chat'te başlat →

Kubernetes

Pod sürekli yeniden başlıyorcentral

Event ve log'lardan nedeni bulur; gerekirse rollout restart ya da scale önerir.

başlangıçkuberneteskubernetes
Chat'te başlat →

Mail

Mail gitmiyor: SMTP kontrolücentral

SMTP connection'ını test eder, onayla bir test e-postası gönderir.

başlangıçmailmail
Chat'te başlat →

Network / VPN

VPN'e yeni cihaz eklecentral

Headscale'de kullanıcıya preauth key üretir, cihazın bağlandığını doğrular.

ilerihttpheadscale
Chat'te başlat →

Güvenlik / Uyum

CIS uyum raporucentral

CIS Ubuntu 24.04 audit'ini çalıştırır, başarısız kontrolleri özetler; hiçbir şeyi değiştirmez.

başlangıçlinuxcis_audit
Chat'te başlat →
SSH sıkılaştırma (şirket standardı)shared

Önce --check --diff ile neyin değişeceğini gösterir, onaydan sonra ssh_hardening'i uygular.

ilerilinuxssh-standart
Chat'te başlat →
Kart = skill. Kart metni opentag.card'dan, kategori opentag.category'den, rozet opentag.audience'tan, gereken capability opentag.requires'tan, kaynak skill'in central ya da shared oluşundan gelir. shared kartlar şirketin kendi skill'leridir (örnek adlar). "Başlangıç" filtresi açılış ekranındaki kartlarla aynı veridir.
Tasarım mock'u karttan açılan console sohbeti (#33) · onay kartı Faz 2 (#25)
opentag.nesiler.com/sohbet
Sunucumun diski doldu, yardım eder misin?Katalog · Disk doldu

disk-doldu skill'ini izliyorum. Hangi sunucu?

● web-01 (site-ofis/ssh/web-01)○ db-01○ Listede yok
ssh_read web-01 · df -h, du -xh /var | sort -h read · onaysız

/ %97 dolu. En büyükleri: /var/log/journal 6,2 GB, eski .tar.gz yedekleri 3,1 GB. Ne yapalım?

● Journal'ı 500 MB'a indir○ Eski yedekleri de sil○ Yalnız rapor
Onay bekliyorwrite · medium
Tool
ssh_run · journalctl --vacuum-size=500M
Connection
site-ofis/ssh/web-01 · server agent
Etki
Eski journal kayıtları silinir, yaklaşık 5,7 GB açılır
Geri alma
Silinen log geri gelmez; servisler etkilenmez
Doğrulama
Ardından df -h /
OnaylaReddet
ssh_run job server agent'ta · ticket doğrulandı done · ardından ssh_read df -h / → %38

Disk %38'e indi. Bu çözümü bu sunucu için bir shared skill olarak kaydetmemi ister misin?

Sorular OpenCode'un soru tool'uyla seçenekli gelir. Connection adları örnektir.

Nasıl çalışır

  1. Kart listesi. Console GET /v1/skills ile tenant'ın skill'lerini (central + shared) metadata'larıyla alır ve opentag.category'ye göre gruplar. skill repo, sync metadata: Faz 3 (#30)
  2. Chat'te başlat. Console sohbeti açar ve opentag.starter cümlesini ilk mesaj olarak yazar. Sohbet console relay ile PC'deki OpenCode'da çalışır. Faz 3 (#28, #29, #33, #34)
  3. AI skill'i yükler. Skill bundle sync ile PC'de zaten vardır; OpenCode skill'i yükler ve adımlarını izler. Çalışıyor
  4. Seçenekli sorular. Sunucu, kapsam, yöntem gibi kararlar seçenekli sorularla alınır; kullanıcı komut yazmaz. soru tool'u console formu: Faz 3 (#33)
  5. Read tool'lar ve preview. ssh_read, k8s_get, ansible_check (--check --diff) gibi read adımları onaysız çalışır; connection başka agent'taysa job olarak gider. Çalışıyor
  6. Onay kartı. Write adımı planıyla (hedef, etki, geri alma, doğrulama) console'da onay kartı olur; onay yalnız Zitadel session'ıyla verilir. Faz 2 (#18, #25) Bugün aynı adım OpenCode'un permission prompt'una düşer.
  7. Job doğru agent'ta. Platform imzalı ticket'la job'ı connection'ın bulunduğu agent'a (çoğu zaman server agent) gönderir; agent ticket'ı ve local allowlist'i doğrular. job routing ticket: Faz 2 (#19, #20)
  8. Sonuç ve audit. AI sonucu read tool'la doğrular ve özetler; agent'ta audit.log yazılır, platformda audit summary Faz 4'te. Çözüm yeni bir skill olarak kaydedilebilir, paylaşılınca kataloğa kart olarak girer. local audit audit summary: Faz 4 (#41)
Katalog kartından onaylı write'aConsole (Katalog)PlatformOpenCode (PC)opentagd --serverGET /v1/skills → metadata (central + shared)Chat'te başlat → opentag.starter/v1/relay/{agent_id}/… · starter mesajıWSS relay.open → local OpenCodeskill yüklenir (bundle sync ile PC'de)seçenekli soruseçimPOST /v1/jobs ssh_read · policy: allowjob.offerjob.result{status: done, result}POST /v1/jobs ssh_run + plan · policy: askonay kartı (GET /v1/approvals)POST /v1/approvals/{id} approve · Zitadeljob.offer {ticket}ticket + local allowlist · audit.logjob.result{status: done, result}doğrulama ve özet
Katalog kartından onaylı write'a. Faz 2 (onay, ticket) ve Faz 3 (metadata, console chat, relay) parçalarını içerir.

Şirkete göre değişir

  • Katalog tenant'ın skill'lerinden oluşur: herkese gelen central skill'ler ve şirketin kendi shared skill'leri. Şirket sistemlerine göre skill seti ayarlanır; ayrıca bir filtre mantığı yoktur.
  • shared skill'i kidemli_it ve sirket_admini paylaşır; it kullanıcısı kartları görür ve kullanır.
  • opentag.requires kartın gerektirdiği capability'yi gösterir (ör. windows); connection yoksa AI request_connection ile form linki verir.

Bugün ne var, ne gelecek

  • Çalışıyor skill repo, paylaşım ve sync, paketle gelen skill'ler (kubernetes, mail, headscale, ansible …), Ansible catalog'u, job routing.
  • Faz 2 onay kartı, imzalı ticket, PowerShell tool'ları (ad-parola için).
  • Faz 3 skill metadata API'si, Katalog ve başlangıç ekranı, console chat ve relay, pilot skill'ler disk-doldu ve ad-parola (#36).

13 · Deploy ve operasyon

Deploy, CI, release ve geliştirme süreci

Çalışma ortamı

deploy/k8s/
  • k3s; Traefik ingress, cert-manager ile Let's Encrypt (DNS-01) sertifikaları.
  • Namespace'ler: opentag-backend (API, Postgres), opentag-landing (portal), opencode-web (chat UI ve indirmeler), opentag-presentation (bu site).
  • Image'lar local build edilir ve node'un containerd'sine import edilir; registry yok. Her bileşenin deploy.sh'ı vardır.
  • Sunucu tarafı secret'lar k8s secret'larında üretilir ve korunur (SIGNING_SEED, admin token); LiteLLM master key her deploy'da LiteLLM'in secret'ından kopyalanır.

CI

.github/workflows/
  • ci.yml (push, pull request, elle): Go (platform ve agent) vet + test, platform testleri gerçek Postgres servisiyle; agent için darwin/arm64, windows/amd64, linux/amd64 cross-compile; guard plugin testleri ve packager script'lerinin syntax kontrolü; portal next build.
  • security.yml: govulncheck, npm audit, OSV-Scanner.
  • Local'de aynı gate: .agents/check.sh (test Postgres'ini kendisi başlatır).

Release ve paketler

release.yml · v* tag'i
  • OpenCode binary'leri, opentagd, Ansible paketi; ardından macOS DMG, Windows NSIS installer, Linux tar.gz (x64, arm64) ve GitHub release.
  • macOS: ~/Library/Application Support/OpenTag, LaunchAgent. Windows: %LOCALAPPDATA%\OpenTag, oturum açılışında başlar. Linux: systemd --user service. Hiçbiri admin yetkisi istemez.
  • Paketler imzasız (karar: code signing sertifikası şimdilik yok): macOS'ta ilk açılışta sağ tık → Aç, Windows'ta SmartScreen uyarısı. Linux paketi henüz gerçek bir masaüstünde denenmedi.
  • Uninstaller'lar Keychain / Credential Manager kayıtlarını ve çalışma dizinini de siler.

Geliştirme süreci

issue → implement → review → deliver
  • Her task bir GitHub issue'dur; faz başına bir milestone. Her fazın kabul senaryosu vardır ve canlıda çalıştırılır.
  • implement: kendi git worktree'si ve branch'inde; acceptance criteria numaralanır, önce file:line düzeyinde gap analysis, sonra testlerle yalnız delta; gate gerçekten çalıştırılır.
  • review: yazanı görmemiş, farklı modelde yeni bir session; criteria'yı task'tan çıkarır, gate'i yeniden çalıştırır, en az bir guard'ı bilerek bozup testin yakaladığını gösterir. Kimse kendi işini kabul etmez.
  • deliver: squash merge, ilgili bileşenlerin deploy'u, health check ve main'de CI takibi.
  • Auth, migration, secret, prod ve major dependency değişiklikleri owner'ın açık onayını ister.

14 · Yol haritası

Dört faz; her faz bir kabul senaryosuyla biter

Faz 1 · 2-3 gün

Skeleton

Tamamlandı

PC'deki AI, şirket sunucusundaki bir connection'da read job'ını platform üzerinden çalıştırır.

Faz 2 · 3 gün

Onay ve secret

Planlı · 12 issue

AD parola sıfırlama: secret console'dan girilir, job console'da onaylanır, server agent ticket ile çalıştırır.

Faz 3 · 3-4 gün

Console ve repo'lar

Planlı · 11 issue

Pilot senaryosu baştan sona console'dan: Katalog kartı → sohbet → onay → sonuç; skill ve MCP repo, üyeler, limitler.

Faz 4 · 2-3 gün

Hardening

Planlı · 12 issue

Scheduled job'lar, audit, eski kodun kaldırılması, disconnect ve recovery testleri, kurulum belgesi.

Faz kabul edilmeden sonraki faz deploy edilmez. Çalışan akışlar faz boyunca bozulmaz; eski yollar ancak Faz 4'te kaldırılır. Süreler plan tahminidir.

Faz 1 · Skeleton Tamamlandı

Canlı platformda kabul edildi; bağımsız review bir turda kurulum token'ının portal sayfasından denenmediğini bulup reddetti, sayfa üzerinden yapılan testten sonra kabul etti.

Kabul adımıSonuç
1. Ajanlar sayfasından kurulum token'ı, VM'de opentagd install --server, agent aynı sayfada onlineGeçti (token sayfadaki formla üretildi, tekrar kullanım reddedildi, sayfadan revoke)
2. Server agent'ta opentagd secret set ile ssh connection'ıGeçti
3. PC sohbetinde ssh_read df -h platform üzerinden server agent'taGeçti; connection discovery eksiği #65 ile kapatıldı
4. Server agent restart olur, kendiliğinden reconnect olur, bekleyen job teslim edilirGeçti (startup'tan 1 sn sonra; VM reboot'u da denendi)
5. Başka tenant'ın kullanıcısı agent'ı, connection'ı, job'ı göremezGeçti (boş listeler; job, cancel, delete, connection endpoint'lerinde 404)
1.7 ansible_check gerçek bir VM'deki server agent'taGeçti

Kapanan issue'lar: #11 CI'da platform Postgres testleri · #12 PC tool routing · #13 canlıda SQLite → Postgres, WSS ve queue · #14 test VM'leri · #15 Faz 1 kabulü · #51 skill sync testi · #56 backend'in superuser olmayan role ile bağlanması (RLS zorunlu) · #57 Go 1.27.3 toolchain · #58 kesin bekleme süresi ve doğrulanmış cancel · #63 release artefact saklama · #65 site agent connection'larının PC'de listelenmesi.

Faz 2 · Onay ve secret Planlı

Kabul senaryosu

  1. Admin console'dan Windows Server için shared ssh connection'ı (shell: powershell) ekler; parola tarayıcıda şifrelenir, platform log'unda ve veritabanında açık değer yoktur.
  2. AI AD kullanıcısını powershell_read ile bulur, powershell_run ile parolasını sıfırlamak ister; console'da onay kartı çıkar.
  3. Server agent ticket'ı doğrular ve çalıştırır; aynı ticket ikinci kez ticket_invalid.
  4. AI approval endpoint'ini çağıramaz: device token ve MCP key 401.
  5. policy.yaml'da deny_tools: ["powershell_run"]: platform onaylasa bile job reddedilir.
  6. Agent makinesi silinip yeniden kurulur; şifreli backup ve recovery key ile secret'lar geri gelir.
IssueBileşenTask
#16 · 2.1agentTool sınıf/risk tablosu, MCP annotation'ları, hello'da
#17 · 2.2platformPolicy: default'lar, kurallar, en sıkı kazanır, capability-role eşlemesi
#18 · 2.3platformOnaylar: yalnız Zitadel, ask/approval, self-approval engeli, timeout
#19 · 2.4platformTicket imzalama: Ed25519, JWS, JCS, ortak test vector'leri
#20 · 2.5agentTicket doğrulama, jti kaydı, policy.yaml; PC ve server agent'ta
#21 · 2.6agentage secret store, recovery key, backup/restore, secret.put
#23 · 2.7agentpowershell_read / powershell_run
#24 · 2.8platformShared connection ve secret endpoint'leri, grants
#25 · 2.9portalOnay kartı, onay bekleyenler, tarayıcıda age-encryption
#26 · 2.10clientopentag tool'larında OpenCode permission'ı allow, "onay bekleniyor" prompt'u
#22 · 2.11deployWindows Server 2025 test VM'i (AD DS, OpenSSH)
#27 · 2.12kabulKabul senaryosu ve onay bypass denemeleri
Faz 3 · Console ve repo'lar Planlı

Kabul senaryosu

  1. Davetle gelen it kullanıcısı console'da skill kartlarını (Katalog) görür, "Disk doldu" kartında "Chat'te başlat"a tıklar.
  2. Sohbet relay üzerinden açılır, tarayıcı 127.0.0.1'e hiç istek atmaz; AI skill'i izler, seçenekli sorular sorar, temizlik onaydan sonra yapılır.
  3. Admin server agent'a örnek bir MCP server ekler; write tool onaydan geçer.
  4. LLM bütçesi dolunca kullanıcı anlaşılır bir hata görür; admin usage'ı console'da görür.
  5. Admin kullanıcıyı disable eder; cihazı ve LLM key'i hemen çalışmaz olur.
IssueBileşenTask
#28 · 3.1platformRelay: /v1/relay/{agent_id}/*, SSE, path allowlist, yalnız owner
#29 · 3.2agentRelay endpoint'leri: relay.open → local OpenCode ve /opentag/*
#33 · 3.3portalConsole chat: useChat, relay transport'u, seçenekli soru formları
#34 · 3.4portalStarter ve Katalog, skill'ler, MCP, agent'lar, üyeler, policy, usage sayfaları
#30 · 3.5platformSkill metadata, paylaşım role'leri, MCP repo, config.changed
#35 · 3.6agentMCP aggregator: external server'ları çalıştırma ve tek endpoint'ten sunma
#31 · 3.7platformÜyeler, davet, disable, tenant açma script'i
#32 · 3.8platformLiteLLM limitleri: team, bütçe, TPM/RPM, /v1/usage
#36 · 3.9ansibleRehber ve pilot skill'leri (disk-doldu, ad-parola)
#37 · 3.10clientOpenCode config düzeltmeleri, role policy'sine göre bash
#38 · 3.11kabulKabul senaryosu
Faz 4 · Hardening Planlı

Kabul senaryosu

  1. AI gece disk temizliğini schedule etmeyi önerir; standing approval; job gece server agent'ta çalışır, sonuç console'da; argüman değişirse onay düşer.
  2. Admin audit sayfasında kimin, hangi tool ile, hangi connection'da, hangi kararla ne yaptığını görür; komut çıktısı yoktur.
  3. Google, n8n ve merkezi entegrasyonlardan portalda ve API'de iz kalmaz.
  4. Disconnect ve recovery testleri yeşil.
  5. Pilot kurulum belgesi hazır.
IssueBileşenTask
#39 · 4.1platformScheduled job'lar ve standing approval
#40 · 4.1aagentschedule_create MCP tool'u
#43 · 4.2portalScheduled job'lar ve audit sayfaları
#41 · 4.3platformAudit summary, GET /v1/audit
#42 · 4.3aagentaudit.batch
#44 · 4.4platformGoogle, n8n ve merkezi entegrasyonların kaldırılması
#45 · 4.5agentEntegrasyon tool'ları ve tarayıcı → localhost yolunun kaldırılması
#46 · 4.5aclientclient/ altındaki referansların temizlenmesi
#47 · 4.6portalEntegrasyon ve Google sayfalarının kaldırılması
#48 · 4.7deployn8n'in kaldırılması, Postgres backup'ından restore denemesi
#49 · 4.8kabulFailure testleri
#50 · 4.9kabulPilot kurulum belgesi ve release notları

Pilot örnekleri (core'u doğrulamak için)

OrtamÖrnek
PC agentKişisel SSH connection'ıyla disk-doldu: teşhis, seçenekli temizlik, onay, doğrulama
Server agentShared Windows Server connection'ıyla ad-parola: parola sıfırlama, hesap kilidi açma
ScheduledServer agent'ta her gece disk temizliği, standing approval ile
MCPServer agent'ta örnek bir external MCP server; tool'u onaydan geçerek çalışır

15 · Kararlar

Tasarım kararları ve gerekçeleri

Kaynak: docs/kararlar.md. Platform yeri ve şirket sınırı kararları iki ayrı modelin bağımsız danışmasıyla, sekiz maddede mutabakatla verildi (14 Ekim).

KonuKararGerekçe
Platform yeriMVP'de bizim sunucumuzda, multi-tenantTek yönetim noktası, hızlı teslim. Kod single-tenant kurulumu engellemez; müşteride kurulum ileride aynı image ile
Shared secret'larŞirketin server agent'ında, şifreli dosyada; OpenBao yokSecret şirketten çıkmaz, platform yalnız adını bilir; ek bir vault servisi işletmek gerekmez
Şirkette kalan veriSohbet ve ham çıktılar agent tarafındaPlatformda yalnız kullanıcı, catalog, job durumu, onay ve audit summary
İletişimAgent'tan outbound tek WSS/443; queue Postgres'teŞirkette port ve VPN gerekmez; job kaybolmaz (lease, ACK, redelivery)
Console → PCPlatform relayTarayıcıdan localhost erişimi kalkar
OnayEd25519 imzalı tek kullanımlık approval ticket + agent'ta local allowlistAI kendi job'ını onaylayamaz; platform ele geçirilse bile local allowlist geçerli
Generic coreÜrüne özel kod yok; entegrasyonlar skill ya da MCPYeni sistem çoğu zaman bir skill'dir. Pack/Runbook YAML'ı ve template engine (DBOS) bu yüzden kaldırıldı; scheduled job = tek tool çağrısı
VeritabanıPostgres (SQLite'tan geçiş), gooseMulti-tenancy için RLS, queue için row lock (SKIP LOCKED), backup
RuntimeOpenCode fork'u kalırAgent Skills biçimini doğrudan okur; MCP, permission ve SSE API'si olan açık kaynak (MIT) bir runtime ve web UI
UIKendi console'umuz: mevcut portal + shadcn, AI SDK, AI ElementsEn az uğraş, güncel kütüphaneler; chat, tool call, onay, form ve streaming desteği
Model providerŞimdilik DeepSeek, LiteLLM arkasındaProvider değiştirilebilir. Veri koruması ayrı llm-gateway projesinde (Presidio ile masking ve pseudonymization)
Standing approvalDüşük riskli scheduled job'lar içinHer gece aynı job için onay istemek kullanılamaz bir akış olurdu; sınır risk ≤ medium, 90 gün
Sunucuda rootRoot'un secret store'a erişebilmesi kabulStore otomatik açılır; gereksiz karmaşıklık yok
Sunucusuz şirketYalnız PC agent ve sunucu gerektirmeyen işlevlerScheduled job ve shared connection server agent ister (requires_server)
Code signingŞimdilik yokÖnce secret yönetimi; code signing ve auto-update MVP dışı
Google ve n8nBırakıldı, Faz 4'te kaldırılırGeneric core kararıyla çelişir

16 · Teknik SSS

Sık sorulan teknik sorular

Neden platform bizim sunucumuzda, şirketin içinde değil?

MVP'de tek yönetim noktası ve hızlı teslim için. Şirketin yetkisi ve verisi şirkette kalır: secret'lar ve ham çıktılar agent'larda, platform müşteri sistemine kendisi dokunmaz. Kod single-tenant kurulumu engellemez (aynı image, env ile config, her tabloda tenant_id); müşteri sunucusuna kurulum MVP sonrasıdır.

Multi-tenancy nasıl sağlanıyor? Bir tenant başkasının verisini görebilir mi?

Tenant Zitadel org id'sidir ve token'dan gelir. Postgres'te her tabloda tenant_id ve zorunlu RLS var; backend RLS'i atlayamayan opentag_app role'üyle bağlanır, her DB connection'ında app.tenant_id set edilir. Faz 1 kabulünde ikinci tenant'ın kullanıcısı için listeler boş, job ve connection endpoint'leri 404 döndü.

Veriler nerede durur? Sohbetler platforma gelir mi?

Sohbet geçmişi, ham komut çıktıları ve secret'lar agent'larda kalır. Platformda kullanıcı, role, agent, skill, job durumu ve platform üzerinden route edilen job'ın argümanı ile maskelenmiş sonucu durur. LLM'e giden içerik LiteLLM üzerinden model provider'a gider; platform bu içeriği saklamaz ve log'a yazmaz. Kişisel veri maskeleme ayrı llm-gateway projesinde yürür.

Parolalar ve token'lar AI'a gider mi?

Hayır. Değerler portal formuyla girilir, model yalnız secret:// referansı görür, referans opentagd içinde çözülür. Tool çıktıları ve hata mesajlarında bütün connection'ların secret'ları *** olur (düz, JSON, URL-kaçışlı, base64, hex biçimleri). Guard plugin düz secret pattern'i içeren argümanları engeller; argümanda local secret değeri olan job platforma hiç gitmez (secret_in_args). Masking bir security boundary değildir: bir script değeri parçalayıp yazarsa yakalanmaz; bu yüzden script çalıştıran tool write sınıfında ve onaylıdır.

AI kendi job'ını onaylayabilir mi?

Bugün write tool'lar OpenCode'un permission prompt'unda kullanıcı onayına düşer. Faz 2'de approval endpoint'i yalnız Zitadel kullanıcı session'ıyla çağrılır; device token ve MCP key 401 alır. Agent write job'ı ancak tool'a, connection'a ve argüman hash'ine bağlı, imzalı ve tek kullanımlık bir approval ticket ile çalıştırır. Bu, Faz 2 kabul senaryosunun 4. adımıdır.

Platform ele geçirilirse şirkette ne olur?

Bugün (Faz 1) platform policy'si her job'a allow der ve ticket yoktur; bu fazın açık bir sınırıdır. Faz 2'de iki katman gelir: imzalı ticket ve agent'ın local allowlist'i (policy.yaml, sunucuda root'a ait ve 0600). Platform bu dosyayı değiştiremez; örneğin deny_tools: ["powershell_run"] platform onaylasa bile job'ı durdurur. Secret değerleri platformda hiç bulunmaz.

Agent offline ise ya da connection koparsa ne olur?

Agent 25 sn'de bir ping atar; 60 sn sessizlikte offline sayılır ve 1-60 sn arası jitter'lı backoff ile reconnect olur. Agent son 2 dk içinde görülmediyse yeni job 409 agent_offline alır; reconnect ediyor sayılırsa job queue'da bekler. Queue'da 10 dk içinde başlamayan job failed (deadline_exceeded) olur. Faz 1 kabulünde restart edilen agent startup'tan 1 sn sonra bağlanıp bekleyen job'ı aldı.

Bir job iki kez çalışabilir mi?

Read job güvenle redeliver edilir. Agent ack göndermeden koparsa ya da lease dolarsa job attempt+1 ile redeliver edilir. ack'ten sonra kopan write job unknown olur ve kendiliğinden tekrarlanmaz. Agent biten job'ların sonucunu saklar; aynı job_id tekrar gelirse tool'u yeniden çalıştırmadan saklanan sonucu gönderir. Yarıda kesilen çağrının cancel'ı doğrulanamazsa AI'a durumu önce read tool ile kontrol etmesi söylenir.

Nasıl ölçeklenir?

Bugün platform tek replica çalışır. Job durumu Postgres'tedir ve dispatch FOR UPDATE SKIP LOCKED ile yapılır; agent başına aynı anda en çok 8 job çalışır. Agent'ların WSS connection'ları ve long-poll istekleri process belleğindedir; birden fazla replica'ya geçmek için connection'ın hangi replica'da olduğunu bilen bir routing gerekir. MVP'de buna yönelik bir task yok. Ağır iş (tool çalıştırma) zaten agent'larda, yani şirket tarafında dağıtıktır.

Hangi model kullanılıyor, maliyet nasıl kontrol ediliyor?

Bugün DeepSeek: ana agent deepseek-flash-deepseek, uzman subagent deepseek-pro-deepseek. Model erişimi LiteLLM arkasındadır, sağlayıcı değiştirilebilir. Her kullanıcının kendi LiteLLM key'i vardır ve harcaması /v1/me/usage ile görülür. Faz 3'te şirket başına bütçe, TPM/RPM, izinli modeller ve kullanıcı bütçesi gelir; limit aşımında 429 llm_limit_exceeded. LiteLLM'in sessizce başka modele fallback yapması Faz 3'te düzeltilecek bilinen bir ayar sorunudur.

Neden OpenCode?

Açık kaynak (MIT), tool calling, MCP, permission'lar, subagent ve event stream (SSE) API'si olan hazır bir agent runtime'ı ve web UI'ı. Agent Skills biçimini doğrudan okur, bu yüzden skill repo ek dönüşüm istemez. Fork'ta marka, sabit backend adresi, harici skill dizinlerinin kapatılması, terminalin ve upstream'e giden connection'ların kaldırılması gibi değişiklikler var; yerleşik build/plan agent'ları kapalı.

Neden Postgres, neden Go?

Postgres: multi-tenancy'yi veritabanı düzeyinde zorlayan RLS, queue için row lock'lar, olgun backup. SQLite'tan bu yüzden geçildi. Go: agent tek statik binary olarak macOS, Windows ve Linux'a cross-compile edilir (CI her push'ta üçünü build eder); platform stdlib net/http ile tek servistir.

Windows desteği ne durumda?

PC uygulaması Windows x64 için NSIS installer ile gelir, kullanıcı hesabı altında çalışır, secret'lar Credential Manager'dadır. Server agent Windows'ta service olarak kurulur; Windows server agent'ta Ansible tool'ları yoktur (Ansible Windows'ta control node olamaz). Windows sunucuları yönetmek için powershell_read / powershell_run (Windows'un OpenSSH'ı üzerinden) Faz 2'de gelir ve Windows Server 2025 test VM'inde AD komutlarıyla doğrulanır.

Şirkette port açmak, VPN kurmak gerekir mi?

Hayır. Her agent platforma outbound tek bir WSS connection (443) açar. Server agent hiç local port açmaz; PC agent yalnız 127.0.0.1'de dinler.

Listede olmayan bir sistem nasıl desteklenir?

Çoğu zaman yalnız bir skill yazılır: sistemin http_api, ssh ya da postgres gibi generic bir connection type ile nasıl yönetileceği anlatılır. Yetmezse AI yeni bir connection type tanımlar (define_connection_type); kullanıcı onaylamadan kullanılamaz. Faz 3'te şirket, vendor'ın MCP server'ını MCP repo'ya ekleyebilir; tool'ları aynı onay ve audit'ten geçer.

Çalışan şirketten ayrılınca erişimi nasıl kesilir?

Bugün portaldan cihaz revoke edilir: sonraki istekler 401 device_revoked alır, agent token'ı siler ve bütün endpoint'leri kapatır. Server agent portalın Ajanlar sayfasından revoke edilir ve açık WSS connection'ı kapanır. Faz 3'te kullanıcıyı disable etmek cihazlarını ve LiteLLM key'ini birlikte revoke eder.

Kim ne yaptı, audit nasıl tutulur?

Bugün her agent her MCP çağrısını kendi audit.log'una yazar (zaman, tool, connection, maskeli parametreler, sonuç); platform job'larının durumu jobs tablosundadır. Faz 4'te platformda audit summary gelir: kim, hangi tool, hangi connection, hangi karar, kim onayladı, sonuç ve çıktının sha256'sı. Komut çıktısı ve sohbet platforma gönderilmez.

Tehlikeli komutlar nasıl engelleniyor?

Üç katman var. Guard plugin bash komutlarını parçalarına ayırıp rm -rf, sudo, indirip çalıştırma gibi pattern'leri engeller. ssh_read yalnız allowlist'teki read-only komutları kabul eder. Değişiklik yapan her tool plan ister ve onaya düşer. Guard ve ssh_read filtredir; security boundary Faz 2'de ticket ve local allowlist'tir.

Sunucusu olmayan küçük bir şirket kullanabilir mi?

Evet, yalnız PC agent ile: kişisel connection'lar ve şirket ağı gerektirmeyen işler. Shared connection'lar, scheduled job'lar ve runs_on: site MCP server'ları server agent ister; yoksa requires_server döner.

Backup ve felaket durumunda ne olur?

Platform Postgres'i her gece backup'lanır; backup'tan restore denemesi Faz 4'te (4.7). Server agent'ın secret store'u için Faz 2'de kurulumda bir kez gösterilen recovery key ve opentagd secret backup / restore gelir; makine silinip yeniden kurulunca secret'ların geri gelmesi Faz 2 kabulünün 6. adımıdır.

Uygulama imzalı mı, auto-update var mı?

Hayır, bilinçli bir karar. macOS paketi ad-hoc imzalıdır (ilk açılışta sağ tık → Aç), Windows installer'ı SmartScreen uyarısı verir. Developer ID ve Windows code signing sertifikası ile auto-update MVP dışında.

Kalite nasıl güvence altında?

CI her push ve pull request'te Go testlerini gerçek Postgres'le, agent'ın üç platform için build'ini, guard testlerini ve portal build'ini çalıştırır; ayrıca govulncheck, npm audit ve OSV-Scanner. Her task bağımsız bir review session'ından geçer. Her fazın kabul senaryosu canlıda çalıştırılır. Faz 4'te disconnect, restart, ticket replay ve recovery için failure testleri var.

17 · Linkler ve sözlük

Canlı adresler ve terimler

AdresNe
opentag.nesiler.comPortal: login, indirme, enrollment, agent'lar, connection'lar, skill'ler
api.opentag.nesiler.com/healthzPlatform health check ({"ok":true})
api.opentag.nesiler.com/.well-known/jwks.jsonLocal access token'ı imzalayan Ed25519 public key
chat.opentag.nesiler.comChat UI (OpenCode fork, statik)
wss://api.opentag.nesiler.com/v1/agent/connectAgent connection'ı (device token gerekir)

Repodaki kaynaklar

docs/mvp-mimari.md mimari · docs/islevler.md işlevler · docs/api.md arayüzler (§7 MVP contract'ı) · docs/fazlar/ fazlar ve kabul senaryoları · docs/kararlar.md kararlar.

Sözlük

TenantBir müşteri şirket; Zitadel org'u. Bütün veriler tenant'a bağlıdır.
Agentopentagd. pc (PC agent): IT çalışanının bilgisayarı, kullanıcıya bağlı. site (server agent): şirket sunucusu, şirkete bağlı.
ConnectionBir sisteme erişim tanımı (ssh/web-01); secret'ları agent'ta durur. ID'si <agent_id>/<type>/<name>.
Capabilityopentagd'nin generic tool grubu: linux, windows, kubernetes, database, http, script, mail.
SkillAgent Skills biçiminde bilgi ve yöntem: SKILL.md, references/, scripts/.
MCPModel Context Protocol. opentagd tek MCP endpoint'idir; external MCP server'lar onun arkasında toplanır.
JobPlatform queue'sundaki tek bir tool çağrısı; lease, ACK ve redelivery ile agent'a gider.
Approval ticketOnaylanmış write job için platformun imzaladığı, 10 dk'lık, tek kullanımlık JWS (Faz 2).
Standing approvalScheduled job için tool, connection ve argüman hash'ine bağlı, en çok 90 günlük onay (Faz 4).