{
  "schema": "crystal-vpn.agent-contract/v1",
  "name": "Crystal VPN Organization Administration",
  "description": "Управление доступными организациями, их сотрудниками и VPN-доступом через существующий Workspace API.",
  "documentation": "/vpn/api/remote-access/agent/guide.md",
  "openapi": "/vpn/api/remote-access/agent/openapi.json",
  "authentication": {
    "method": "login_password_to_http_only_session",
    "login_endpoint": "/vpn/api/remote-access/workspace/login",
    "session_endpoint": "/vpn/api/remote-access/workspace/session",
    "csrf": "Use csrf from login/session response in X-CSRF-Token on every POST",
    "credentials": "Never place a password, session cookie, CSRF token, invitation URL or VPN profile URL in prompts, logs or public documents."
  },
  "authorization": {
    "rule": "Every operation is restricted by current server-side account rights and organization assignment.",
    "roles": {
      "organization_owner": "Manage members and roles only in own organization.",
      "organization_deputy": "Manage allowed members in own organization; cannot take owner-only role actions.",
      "corporate_manager": "Manage only organizations explicitly assigned to this manager. Cashback/referrer status alone grants no organization access.",
      "platform_admin": "Existing platform-wide rights."
    }
  },
  "capabilities": [
    "list_accessible_organizations",
    "read_organization",
    "create_member",
    "edit_member_name_or_login",
    "suspend_or_restore_member_access",
    "assign_member_role",
    "remove_member_and_revoke_keys",
    "issue_vpn_profile",
    "suspend_resume_or_rotate_vpn_key",
    "create_installation_link",
    "read_audit",
    "read_referral_overview"
  ],
  "safety": {
    "read_before_write": true,
    "optimistic_concurrency": "Use expected_version from the latest read.",
    "idempotency": "Reuse the same operation_id for retries; never invent a new ID after an uncertain response.",
    "destructive_confirmation": "member/remove and profiles/status rotate require confirmed=true and explicit user intent.",
    "secret_response_fields": [
      "invitation.token",
      "invitation.path",
      "share.share_url"
    ]
  }
}
