API учетных записей для приложений

ℹ️ О документе

Этот раздел описывает программный интерфейс (API) для работы с учетными записями пользователей из внешних приложений. API позволяет получать, создавать, обновлять и удалять учетные записи через HTTP запросы.

Обзор API учетных записей

API учетных записей предоставляет приложениям возможность программно работать с сохраненными учетными данными пользователей. Это полезно для:

  • Автоматической подстановки — получение логинов и паролей для автозаполнения форм
  • Интеграции с системами — автоматическое подключение к серверам, базам данных, API
  • Централизованного хранения — единое безопасное хранилище для всех учетных записей
  • Управления доступом — получение учетных записей с учетом прав пользователя

Аутентификация API

Для использования API учетных записей приложение должно пройти аутентификацию. Существует два способа:

🔑 Через OIDC сессию

Используется для получения учетных записей конкретного пользователя. Требуется идентификатор активной OIDC сессии (session_id).

Применение: получение личных и групповых учетных записей пользователя

🔐 Через Client ID и Secret

Используется для работы с учетными записями приложения. Требуется client_id и client_secret приложения.

Применение: управление учетными записями самого приложения

Базовый URL и формат запросов

Все запросы отправляются на общий endpoint:

POST /service/ext-apps

Формат запроса:

{
  "action": "название_действия",
  "client_id": "идентификатор_приложения",
  "client_secret": "секретный_ключ",
  "data": {
    /* параметры запроса */
  }
}

Формат ответа:

{
  "status": "success|error",
  "data": { /* данные ответа */ },
  "error": "текст ошибки (только при ошибке)"
}

Доступные API методы

Получение списка объектов с учетными записями

Эндпоинт возвращает список всех объектов, для которых у пользователя есть сохраненные учетные записи.

Название действия: getUserObjectsWithCredentials

Параметры запроса:

Параметр Тип Обязательный Описание
user_id string Да Идентификатор пользователя
include_group_credentials boolean Нет Включать ли групповые учетные записи (по умолчанию true)

Пример запроса:

{
  "action": "getUserObjectsWithCredentials",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {
    "user_id": "user123",
    "include_group_credentials": true
  }
}

Пример ответа:

{
  "status": "success",
  "data": {
    "object_paths": [
      "/app123/servers/web01",
      "/app123/databases/mysql01",
      "/app123"
    ],
    "user_id": "user123",
    "application_id": "app123",
    "count": 3
  }
}

Получение лучших учетных записей для объектов

Эндпоинт возвращает наиболее подходящие учетные записи для списка объектов с учетом приоритетов и предпочтительных типов.

Название действия: getBestCredentialsForObjects

✨ Рекомендуется

Это основной метод для получения учетных записей. Он автоматически выбирает наиболее подходящую учетную запись с учетом приоритетов (личные → групповые) и типов.

Параметры запроса:

Параметр Тип Обязательный Описание
session_id string Да Идентификатор активной OIDC сессии
object_requests array Да Массив запросов объектов

Структура объекта в object_requests:

Поле Тип Обязательное Описание
object_path string Да Путь к объекту (относительно приложения)
preferred_type string Нет Предпочтительный тип учетной записи

Пример запроса:

{
  "action": "getBestCredentialsForObjects",
  "data": {
    "session_id": "oidc_session_123",
    "object_requests": [
      {
        "object_path": "/servers/web01",
        "preferred_type": "ssh"
      },
      {
        "object_path": "/databases/mysql01",
        "preferred_type": "rdp"
      },
      {
        "object_path": "/api/service01"
      }
    ]
  }
}

Пример ответа:

{
  "status": "success",
  "data": {
    "credentials": [
      {
        "object_path": "/servers/web01",
        "preferred_type": "ssh",
        "credential": {
          "id": 123,
          "title": "Админский доступ к web01",
          "type": "ssh",
          "content": {
            "domain": "",
            "login": "admin",
            "password": "",
            "privateKey": "-----BEGIN RSA PRIVATE KEY-----...",
            "passphrase": ""
          },
          "created_at": 1640995200,
          "source": "user",
          "matches_preferred_type": true
        }
      },
      {
        "object_path": "/databases/mysql01",
        "preferred_type": "rdp",
        "credential": {
          "id": 456,
          "title": "Групповая УЗ MySQL",
          "type": "universal",
          "content": {
            "domain": "",
            "login": "dbuser",
            "password": "encrypted_password",
            "privateKey": "",
            "passphrase": ""
          },
          "created_at": 1640995300,
          "source": "group",
          "matches_preferred_type": false
        }
      },
      {
        "object_path": "/api/service01",
        "preferred_type": null,
        "credential": null
      }
    ],
    "user_id": "user123",
    "session_id": "oidc_session_123",
    "application_id": "app123",
    "count": 3
  }
}

Логика приоритизации учетных записей

При поиске учетной записи система применяет следующую логику приоритетов:

  1. Приоритет 1: Личная учетная запись с указанным типом (если preferred_type задан)
  2. Приоритет 2: Групповая учетная запись с указанным типом
  3. Приоритет 3: Личная универсальная учетная запись (тип universal)
  4. Приоритет 4: Групповая универсальная учетная запись
ℹ️ Поиск по дереву

Если на указанном объекте учетная запись не найдена, система автоматически поднимается вверх по дереву объектов до корня приложения. Например, для объекта /servers/web01/service1 поиск пройдет через /servers/web01, затем /servers, и наконец корень приложения.

Типы учетных записей

API поддерживает следующие типы учетных записей:

Тип Описание Применение
rdp RDP (Remote Desktop Protocol) Подключение к удаленным рабочим столам Windows
ssh SSH ключи и пароли Подключение к Linux серверам по SSH
universal Универсальная учетная запись Любые логины и пароли без конкретного типа

Структура учетной записи в ответе

Каждая учетная запись содержит следующие поля:

Поле Тип Описание
id integer Уникальный идентификатор учетной записи
title string Название учетной записи
type string Тип учетной записи (rdp, ssh, universal)
content object Содержимое учетной записи (логин, пароль, ключи)
created_at integer Время создания (Unix timestamp)
source string Источник: user (личная) или group (групповая)
matches_preferred_type boolean Соответствует ли найденная запись предпочтительному типу

Структура поля content:

Поле Тип Описание
domain string Домен (для Windows RDP)
login string Имя пользователя
password string Пароль (расшифрованный)
privateKey string SSH приватный ключ (для типа SSH)
passphrase string Парольная фраза для SSH ключа
⚠️ Безопасность данных

Все пароли и приватные ключи передаются в расшифрованном виде, поэтому обязательно используйте HTTPS для всех запросов к API. Никогда не логируйте и не сохраняйте расшифрованные данные в открытом виде.

API для учетных записей приложения

Приложения могут хранить собственные учетные записи, не связанные с конкретными пользователями. Это полезно для:

  • Сервисных аккаунтов и API ключей
  • Токенов доступа к внешним системам
  • Конфигурационных параметров с секретами

Сохранение учетной записи приложения

Название действия: saveApplicationCredential

Параметры запроса:

Параметр Тип Обязательный Описание
credential_id integer Нет ID для обновления существующей (если не указан — создается новая)
object_id string Да Идентификатор объекта
type string Да Тип учетной записи
title string Нет Название учетной записи
content object Да Содержимое (логин, пароль, ключи)

Пример запроса (создание новой):

{
  "action": "saveApplicationCredential",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {
    "object_id": "external-api",
    "type": "universal",
    "title": "API ключ внешнего сервиса",
    "content": {
      "domain": "",
      "login": "api_user",
      "password": "api_key_12345",
      "privateKey": "",
      "passphrase": ""
    }
  }
}

Пример запроса (обновление существующей):

{
  "action": "saveApplicationCredential",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {
    "credential_id": 789,
    "object_id": "external-api",
    "type": "universal",
    "title": "API ключ внешнего сервиса (обновлен)",
    "content": {
      "domain": "",
      "login": "api_user",
      "password": "new_api_key_67890",
      "privateKey": "",
      "passphrase": ""
    }
  }
}

Получение учетной записи приложения

Название действия: getApplicationCredential

Параметры запроса:

Параметр Тип Обязательный Описание
object_id string Да Идентификатор объекта
type string Да Тип учетной записи

Пример запроса:

{
  "action": "getApplicationCredential",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {
    "object_id": "external-api",
    "type": "universal"
  }
}

Пример ответа:

{
  "status": "success",
  "data": {
    "credential": {
      "id": 789,
      "object_id": "external-api",
      "type": "universal",
      "title": "API ключ внешнего сервиса",
      "content": {
        "domain": "",
        "login": "api_user",
        "password": "api_key_12345",
        "privateKey": "",
        "passphrase": ""
      },
      "created_at": 1640995200
    }
  }
}

Массовое получение учетных записей приложения

Название действия: getApplicationCredentialsBulk

Позволяет получить несколько учетных записей за один запрос.

Параметры запроса:

Параметр Тип Обязательный Описание
requests array Да Массив запросов (каждый с object_id и type)

Пример запроса:

{
  "action": "getApplicationCredentialsBulk",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {
    "requests": [
      {
        "object_id": "external-api",
        "type": "universal"
      },
      {
        "object_id": "database-server",
        "type": "universal"
      }
    ]
  }
}

Пример ответа:

{
  "status": "success",
  "data": {
    "credentials": [
      {
        "object_id": "external-api",
        "type": "universal",
        "credential": {
          "id": 789,
          "title": "API ключ",
          "content": { /* ... */ },
          "created_at": 1640995200
        }
      },
      {
        "object_id": "database-server",
        "type": "universal",
        "credential": null
      }
    ],
    "count": 2
  }
}

Список всех учетных записей приложения

Название действия: listApplicationCredentials

Возвращает все учетные записи, сохраненные приложением.

Пример запроса:

{
  "action": "listApplicationCredentials",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {}
}

Пример ответа:

{
  "status": "success",
  "data": {
    "credentials": [
      {
        "id": 789,
        "object_id": "external-api",
        "type": "universal",
        "title": "API ключ",
        "created_at": 1640995200
      },
      {
        "id": 790,
        "object_id": "database-server",
        "type": "universal",
        "title": "БД credentials",
        "created_at": 1640995300
      }
    ],
    "count": 2
  }
}
ℹ️ Без расшифровки

Метод listApplicationCredentials возвращает только метаданные (ID, название, тип, дата создания) без расшифровки содержимого (content). Для получения паролей и ключей используйте getApplicationCredential или getApplicationCredentialsBulk.

Удаление учетной записи приложения

Название действия: deleteApplicationCredential

Параметры запроса:

Параметр Тип Обязательный Описание
credential_id integer Да ID учетной записи для удаления

Пример запроса:

{
  "action": "deleteApplicationCredential",
  "client_id": "app123",
  "client_secret": "secret456",
  "data": {
    "credential_id": 789
  }
}

Безопасность API

Шифрование данных

Все учетные записи хранятся в зашифрованном виде в базе данных IDENTYX:

  • Шифрование в БД — данные шифруются перед сохранением
  • Расшифровка при запросе — данные расшифровываются только при обращении через API
  • Уникальные ключи — для каждого пользователя и приложения используются уникальные ключи шифрования

Обязательное использование HTTPS

🚫 Требование безопасности

API учетных записей должен использоваться ТОЛЬКО через HTTPS. Передача паролей и ключей по незащищенному HTTP соединению создает критическую угрозу безопасности.

Контроль доступа

Система проверяет права доступа на каждый запрос:

  • Пользовательские учетные записи — доступны только владельцу и членам групп
  • Групповые учетные записи — доступны только членам группы
  • Учетные записи приложения — доступны только самому приложению через client_secret

Обработка ошибок

При возникновении ошибки API возвращает ответ с status: "error":

{
  "status": "error",
  "error": "Описание ошибки"
}

Частые ошибки

Ошибка Причина Решение
Приложение не найдено Неверные client_id или client_secret Проверьте учетные данные приложения
Сессия не найдена или истекла Недействительный session_id Получите новый session_id через OIDC
Учетная запись не найдена Нет УЗ для указанного объекта/типа Проверьте наличие УЗ для пользователя
Не указан обязательный параметр Отсутствует required параметр Добавьте недостающий параметр в запрос

Лучшие практики

Кеширование

  • Не кешируйте расшифрованные данные — храните только зашифрованные
  • Кешируйте список объектов — результаты getUserObjectsWithCredentials можно кешировать на 1-5 минут
  • Инвалидация кеша — сбрасывайте кеш при изменении учетных записей

Производительность

  • Используйте getBestCredentialsForObjects для получения нескольких учетных записей за один запрос
  • Используйте getApplicationCredentialsBulk для массовых операций
  • Не запрашивайте учетные записи слишком часто — кешируйте результаты

Логирование

⚠️ Важно для безопасности

Никогда не логируйте расшифрованные пароли, приватные ключи или другие секретные данные. Логируйте только факт обращения к API и результат операции (успех/ошибка).

Примеры интеграции

Пример на PHP

<?php

class IdentyxCredentialsAPI
{
    private $baseUrl;
    private $clientId;
    private $clientSecret;
    
    public function __construct($baseUrl, $clientId, $clientSecret)
    {
        $this->baseUrl = $baseUrl;
        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
    }
    
    /**
     * Получить лучшие учетные записи для списка объектов
     */
    public function getBestCredentials($sessionId, $objectRequests)
    {
        $payload = [
            'action' => 'getBestCredentialsForObjects',
            'data' => [
                'session_id' => $sessionId,
                'object_requests' => $objectRequests
            ]
        ];
        
        return $this->makeRequest($payload);
    }
    
    /**
     * Сохранить учетную запись приложения
     */
    public function saveAppCredential($objectId, $type, $content, $title = null, $credentialId = null)
    {
        $data = [
            'object_id' => $objectId,
            'type' => $type,
            'content' => $content
        ];
        
        if ($title) {
            $data['title'] = $title;
        }
        
        if ($credentialId) {
            $data['credential_id'] = $credentialId;
        }
        
        $payload = [
            'action' => 'saveApplicationCredential',
            'client_id' => $this->clientId,
            'client_secret' => $this->clientSecret,
            'data' => $data
        ];
        
        return $this->makeRequest($payload);
    }
    
    /**
     * Получить учетную запись приложения
     */
    public function getAppCredential($objectId, $type)
    {
        $payload = [
            'action' => 'getApplicationCredential',
            'client_id' => $this->clientId,
            'client_secret' => $this->clientSecret,
            'data' => [
                'object_id' => $objectId,
                'type' => $type
            ]
        ];
        
        return $this->makeRequest($payload);
    }
    
    /**
     * Удалить учетную запись приложения
     */
    public function deleteAppCredential($credentialId)
    {
        $payload = [
            'action' => 'deleteApplicationCredential',
            'client_id' => $this->clientId,
            'client_secret' => $this->clientSecret,
            'data' => [
                'credential_id' => $credentialId
            ]
        ];
        
        return $this->makeRequest($payload);
    }
    
    private function makeRequest($payload)
    {
        $ch = curl_init($this->baseUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode !== 200) {
            throw new Exception("HTTP Error: $httpCode");
        }
        
        $result = json_decode($response, true);
        
        if ($result['status'] !== 'success') {
            throw new Exception($result['error'] ?? 'Unknown error');
        }
        
        return $result['data'];
    }
}

// Использование
$api = new IdentyxCredentialsAPI(
    'https://iam.example.com/service/ext-apps',
    'app123',
    'secret456'
);

// Получить учетные записи пользователя
try {
    $credentials = $api->getBestCredentials('session_id_123', [
        ['object_path' => '/servers/web01', 'preferred_type' => 'ssh'],
        ['object_path' => '/databases/mysql01', 'preferred_type' => 'rdp']
    ]);
    
    foreach ($credentials['credentials'] as $item) {
        if ($item['credential']) {
            echo "Найдена УЗ для {$item['object_path']}\n";
            echo "Логин: {$item['credential']['content']['login']}\n";
        }
    }
} catch (Exception $e) {
    error_log("Ошибка API: " . $e->getMessage());
}

// Сохранить учетную запись приложения
try {
    $api->saveAppCredential(
        'external-service',
        'universal',
        [
            'domain' => '',
            'login' => 'service_user',
            'password' => 'secret_password_123',
            'privateKey' => '',
            'passphrase' => ''
        ],
        'Учетная запись внешнего сервиса'
    );
    
    echo "Учетная запись сохранена\n";
} catch (Exception $e) {
    error_log("Ошибка сохранения: " . $e->getMessage());
}
?>

Пример на JavaScript

class IdentyxCredentialsAPI {
    constructor(baseUrl, clientId, clientSecret) {
        this.baseUrl = baseUrl;
        this.clientId = clientId;
        this.clientSecret = clientSecret;
    }
    
    async getBestCredentials(sessionId, objectRequests) {
        const payload = {
            action: 'getBestCredentialsForObjects',
            data: {
                session_id: sessionId,
                object_requests: objectRequests
            }
        };
        
        return await this.makeRequest(payload);
    }
    
    async saveAppCredential(objectId, type, content, title = null, id = null) {
        const data = {
            object_id: objectId,
            type: type,
            content: content
        };
        
        if (title) data.title = title;
        if (id) data.id = id;
        
        const payload = {
            action: 'saveApplicationCredential',
            client_id: this.clientId,
            client_secret: this.clientSecret,
            data: data
        };
        
        return await this.makeRequest(payload);
    }
    
    async getAppCredential(objectId, type) {
        const payload = {
            action: 'getApplicationCredential',
            client_id: this.clientId,
            client_secret: this.clientSecret,
            data: {
                object_id: objectId,
                type: type
            }
        };
        
        return await this.makeRequest(payload);
    }
    
    async makeRequest(payload) {
        const response = await fetch(this.baseUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(payload)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP Error: ${response.status}`);
        }
        
        const result = await response.json();
        
        if (result.status !== 'success') {
            throw new Error(result.error || 'Unknown error');
        }
        
        return result.data;
    }
}

// Использование
const api = new IdentyxCredentialsAPI(
    'https://iam.example.com/service/ext-apps',
    'app123',
    'secret456'
);

// Получить учетные записи
api.getBestCredentials('session_123', [
    { object_path: '/servers/web01', preferred_type: 'ssh' },
    { object_path: '/databases/mysql01', preferred_type: 'rdp' }
])
.then(data => {
    data.credentials.forEach(item => {
        if (item.credential) {
            console.log(`УЗ для ${item.object_path}:`, item.credential.content.login);
        }
    });
})
.catch(err => {
    console.error('Ошибка API:', err.message);
});
✅ Готовы продолжить?

Вы изучили все доступные методы API учетных записей. Для дальнейшего изучения переходите к разделам по администрированию системы.