Автентифікація та ролі

Огляд

Private Channels включає необов'язковий Auth Service, який обмежує доступ до шлюзу за допомогою JWT-автентифікації та рольового контролю доступу (RBAC). Коли автентифікацію вимкнено, шлюз приймає всі з'єднання. Коли увімкнено, клієнти повинні надавати дійсний JWT у кожному запиті.

Ця сторінка охоплює обидві аудиторії:

  • Розробники — реєстрація, вхід, верифікація гаманця та виконання автентифікованих запитів
  • Оператори — увімкнення auth service, налаштування JWT_SECRET і надання ролі operator

Увімкнення автентифікації

Автентифікацію увімкнено шляхом встановлення JWT_SECRET (непорожнього) як на шлюзі, так і в Auth Service. Auth Service також вимагає AUTH_DATABASE_URL.

Якщо JWT_SECRET не встановлено, шлюз працює у відкритому режимі; токен не потрібен.

Docker Compose: Auth service є профілем Docker Compose і не запускається за замовчуванням. Щоб увімкнути його, передайте --profile auth до команди docker compose, включаючи --env-file .env, щоб секрети на кшталт JWT_SECRET і POSTGRES_PASSWORD дійсно підставлялися (Compose вимикає автоматичне завантаження .env після передачі будь-якого прапора --env-file):

docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet --env-file .env --profile auth up -d

API Auth Service

Усі ендпоінти знаходяться під /auth. Auth service слухає на AUTH_PORT (за замовчуванням 8903).

POST /auth/register

Створення нового облікового запису. Усі користувачі реєструються з роллю user.

{ "username": "alice", "password": "hunter2" }
  • Ім'я користувача: 5–32 символи, літерно-цифрові плюс _ та -
  • Пароль: 6–128 символів
  • Повертає створеного користувача; пароль ніколи не повертається

POST /auth/login

Автентифікація та отримання підписаного JWT, дійсного протягом 24 годин.

{ "username": "alice", "password": "hunter2" }

Повертає { "token": "<jwt>" }. Як неправильне ім'я користувача, так і неправильний пароль повертають 401, щоб запобігти перебору імен користувачів.

POST /auth/challenge-wallet

Запит підписувального виклику для підтвердження права власності на гаманець Solana. Потрібен дійсний JWT.

Повертає повідомлення, nonce та термін дії. Виклик дійсний протягом 10 хвилин.

{
"message": "PrivateChannel wallet verification\nuser: <uuid>\nnonce: <uuid>\nexpires: <unix>",
"nonce": "<uuid>",
"expires_at": "<iso8601>"
}

POST /auth/verify-wallet

Надіслати підписаний виклик для реєстрації гаманця як верифікованого. Потрібен дійсний JWT.

{
"pubkey": "<base58 pubkey>",
"nonce": "<uuid from challenge>",
"signature": "<base58 Ed25519 signature>"
}

Сервіс відновлює повідомлення виклику, перевіряє підпис Ed25519 та зберігає гаманець. Кожен nonce може бути використаний лише один раз; повторні запити відхиляються.

Повертає { "pubkey": "<base58>", "created_at": "<iso8601>" }.

GET /auth/wallets

Список усіх верифікованих гаманців автентифікованого користувача. Потрібен дійсний JWT.

DELETE /auth/wallets/{pubkey}

Видалення верифікованого гаманця з облікового запису автентифікованого користувача. Потрібен дійсний JWT.

GET /health

Перевірка працездатності. Повертає 200 ok. Автентифікація не потрібна.

Структура JWT

Токени використовують алгоритм HS256 і закінчуються через 24 години після видачі.

ClaimЗначення
subUUID користувача
role"user" або "operator"
iss"private-channel-auth"
aud"private-channel-gateway"
expUnix timestamp (24 год. від видачі)

iss і aud присутні в payload JWT, але перевіряються конфігурацією JWT шлюзу, а не десеріалізуються у структуру claims застосунку. Код на рівні застосунку має доступ лише до sub, role та exp.

Передайте токен у заголовку Authorization:

Authorization: Bearer <JWT_TOKEN>

Ролі

user

Роль за замовчуванням при реєстрації.

  • Доступ обмежено власними верифікованими гаманцями користувача
  • Заблоковано: getBlock, getTransaction, simulateTransaction
  • Може: викликати Deposit на Escrow Program, ініціювати виведення коштів через WithdrawFunds

operator

Підвищена роль. Надається виключно вручну; самостійного шляху для підвищення з user до operator не існує.

Надати роль, або через Admin CLI (private-channel-auth-admin):

private-channel-auth-admin set-role --username alice --role operator

або за допомогою прямого SQL:

Це привілейована операція з базою даних. Обмежте доступ до бази даних Auth Service відповідним чином і ведіть аудит будь-яких змін ролей.

UPDATE private_channel_auth.users SET role = 'operator' WHERE username = 'alice';

Реєстрація гаманця без самостійного процесу верифікації (Admin CLI, private-channel-auth-admin):

private-channel-auth-admin attach-wallet --username alice --pubkey <base58-pubkey>

Ця команда безпосередньо вставляє верифікований гаманець до таблиці verified_wallets, обходячи процес challenge/verify. Забезпечує унікальне обмеження на (user_id, pubkey). Вона не надає роль operator сама по собі; використовуйте set-role або наведений вище SQL-запит для цього. Ця команда призначена для прив'язки гаманця до облікового запису (наприклад, службового акаунта) без необхідності проходити інтерактивний процес challenge/verify.

Можливості:

  • Обходить усі перевірки права власності на гаманець
  • Повний доступ до всіх RPC-методів шлюзу, включаючи getBlock, getTransaction, simulateTransaction
  • Обов'язково для: ReleaseFunds, ResetSmtRoot

Повний процес автентифікації

Виконання автентифікованих запитів

const response = await fetch("http://localhost:8899/", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwtToken}`
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "getBalance",
params: [walletAddress]
})
});
const data = await response.json();

Ендпоінти шлюзу

Ці ендпоінти не потребують автентифікації:

ЕндпоінтМетодОписУспіхПомилка
/healthGETПеревірка працездатності200 {"status":"ok"}-
/readyGETГлибока перевірка готовності; зондує вузли запису та читання200 {"status":"ready"}503 {"status":"degraded"}

Довідник щодо JWT_SECRET та змінних середовища шлюзу наведено в довіднику конфігурації.

Матриця доступу до RPC-методів

Наступні методи розпізнаються шлюзом. Якщо встановлено JWT_SECRET, доступ залежить від ролі JWT:

МетодМаршрутБез JWTuseroperator
sendTransactionВузол запису✓✓✓
getLatestBlockhashВузол читання✓✓✓
getSlotВузол читання✓✓✓
getRecentBlockhashВузол читання✓✓✓
getSignatureStatusesВузол читання✓✓✓
getTransactionCountВузол читання✓✓✓
getFirstAvailableBlockВузол читання✓✓✓
getBlocksВузол читання✓✓✓
getEpochInfoВузол читання✓✓✓
getEpochScheduleВузол читання✓✓✓
getRecentPerformanceSamplesВузол читання✓✓✓
getBlockTimeВузол читання✓✓✓
getVoteAccountsВузол читання✓✓✓
getSupplyВузол читання✓✓✓
getSlotLeadersВузол читання✓✓✓
isBlockhashValidВузол читання✓✓✓
getAccountInfoВузол читання401обмежено правом власності¹✓
getTokenAccountBalanceВузол читання401обмежено правом власності¹✓
getSignaturesForAddressВузол читання401обмежено правом власності¹✓
getBlockВузол читання401403✓
getTransactionВузол читання401403✓
simulateTransactionВузол читання401403✓

¹ Обмежено правом власності: для SPL Token account (поле owner має значення TokenkegQ... або TokenzQ..., дані щонайменше 165 байт) шлюз перевіряє, що поле owner або delegate збігається з одним із верифікованих гаманців автентифікованого користувача. Для будь-якого іншого типу акаунта (гаманець System Program або невідомий PDA) замість цього перевіряється, чи є запитуваний pubkey одним із верифікованих гаманців користувача, оскільки такі акаунти не мають поля owner/delegate для перевірки. Якщо будь-яка з перевірок не проходить — повертається 403.

Is this page helpful?