Вход через URnetwork
Позвольте людям допускать ваше приложение или агента в свою приватную сеть, чтобы оно могло координироваться со всем остальным, что у них там работает.
Скачайте набор для кнопки — разметка, стили, оба варианта в виде отдельных ассетов и знак сам по себе. Набор окончательный, и вы можете внедрить его уже сегодня, раньше всего остального на этой странице.
В разработке — ещё не запущено. Эта страница описывает проект, который ещё строится. Сервер авторизации написан, но не развёрнут:
auth.bringyour.comпока не резолвится, и ни один из эндпоинтов ниже сегодня вызвать нельзя.client_idвыдаются по запросу, а не в режиме самообслуживания. Всё, что помечено как запланировано, не построено. Набор для кнопки настоящий и окончательный, и вы можете внедрить его уже сейчас.
Что это такое
Вход — это шаг допуска. Он даёт место в сети — адресуемое, обнаружимое другими программами этого человека и отзываемое им в любой момент.
Этим он отличается от кнопок входа, на которые похож. Главное здесь не в том, чтобы узнать, кто перед вами. Вас куда-то впускают.
Разрешение состоит из двух половин, на которые соглашаются и которые отзывают по отдельности:
- Идентичность — то, что аккаунт URnetwork одобрил вас, и ничего больше.
- Сеть — в какой сети вы можете действовать; она названа на экране согласия и вшита в токен при его выдаче.
Приложение может запросить только идентичность. Вход никогда не подразумевает доступа к сети.
Кнопка
Используйте тёмную кнопку на светлых поверхностях и поверхностях среднего тона, светлую — на тёмных. Размещённого скрипта нет: набор — это HTML, CSS и один встроенный SVG, поэтому кнопка на вашей странице ничего не передаёт, пока кто-нибудь на неё не нажмёт.
Где можете, предпочитайте разметку ниже SVG-ассетам: тогда подпись отрисовывается шрифтом вашей страницы и остаётся выделяемой, доступной для поиска и перевода. Отдельные SVG-ассеты из набора — для мест, которые принимают изображение и ничего больше.
На кнопке написано Sign in with, а следом идёт локап URnetwork. Текстом является только первая часть, и именно поэтому кнопка чисто переводится: выводите «Sign in with» на языке своего интерфейса и не трогайте локап, чтобы бренд везде читался одинаково.
<a class="ur-signin" href="YOUR_AUTHORIZE_URL" aria-label="Sign in with URnetwork">
<span>Sign in with</span>
<svg class="ur-signin-lockup" viewBox="0 0 980 139" fill="currentColor" aria-hidden="true">
<!-- the lockup, 10 paths — copy them from the kit -->
</svg>
</a>Локап нарисован с currentColor, поэтому наследует цвет текста кнопки, и одна копия служит обоим вариантам. aria-label несёт имя целиком, поскольку половина его — графика.
.ur-signin {
display: inline-flex; align-items: center; gap: 10px;
height: 44px; padding: 0 20px; min-width: 200px;
border-radius: 12px; border: 1px solid transparent;
background: #101010; color: #f8f8f8;
font: 500 15px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
text-decoration: none; white-space: nowrap; cursor: pointer;
}
.ur-signin:hover { background: #1c1c1c; }
.ur-signin:focus-visible { outline: 2px solid #0099ff; outline-offset: 2px; }
.ur-signin-lockup { height: 16px; width: auto; flex: none; }
/* Light variant, for dark surfaces */
.ur-signin.is-light { background: #f8f8f8; color: #101010; border-color: rgba(16,16,16,.14); }
.ur-signin.is-light:hover { background: #ececec; }Подпись использует системный стек шрифтов, а не фирменный шрифт URnetwork, который нельзя распространять на другие сайты, — а подключение веб-шрифта вернуло бы в кнопку сетевой запрос.
Правила бренда
| Высота | Минимум 44px — это же и зона касания. Никогда не меньше. |
| Радиус скругления | 12px |
| Локап | Высота 16px, currentColor; никогда не перерисовывается, не перекрашивается и не собирается заново из частей |
| Охранное поле | 8px со всех четырёх сторон |
| Кольцо фокуса | 2px #0099ff, отступ 2px |
| Фон | #101010 — тёмный, #f8f8f8 — светлый. Никакого другого цвета, никакого градиента. |
Не набирайте слово URnetwork своим шрифтом вместо локапа, не используйте знак без подписи, не анимируйте и не наклоняйте кнопку. Переводите «Sign in with» на язык своего интерфейса; локап не меняется никогда.
Как это работает
Запланировано. Эндпоинты ниже не развёрнуты.
Код авторизации с PKCE — и ничего больше: это OAuth 2.1, поэтому неявного гранта (implicit grant) нет, а S256 обязателен.
| Издатель | https://auth.bringyour.com |
| Обнаружение | /.well-known/openid-configuration и /.well-known/oauth-authorization-server |
| Ключи | /.well-known/jwks.json |
| Авторизация | https://ur.io/authorize |
| Токен | POST /oauth/token |
| UserInfo | GET /oauth/userinfo |
| Отзыв | POST /oauth/revoke |
Эндпоинт авторизации намеренно находится на другом источнике (origin), чем издатель. Экрану согласия нужно переиспользовать сеанс, в котором уже выполнен вход, а хранилище браузера привязано к источнику, поэтому страница живёт там, где сеанс уже есть. RFC 8414 это допускает, и идентичность издателя не затрагивается — продолжайте проверять iss по auth.bringyour.com.
Согласие всегда показывается, когда вы впервые запрашиваете данный набор областей доступа, даже если человек уже вошёл. Если бы страница молча одобряла третью сторону, она стала бы запутавшимся заместителем (confused deputy).
Присоединение к сети
Запланировано.
Токен доступа OAuth авторизует; по протоколу connect он не говорит. Чтобы занять место в сети, которое вам предоставили, обменяйте его:
POST /network/auth-client
Authorization: Bearer <access token>Вы получаете JWT платформы с clientId — адресом, по которому вас знает протокол. Дальше вы — обычный участник этой сети, а через /network/peers вы узнаёте, что ещё в неё допущено.
Три вещи удивляют людей:
- Это единственный переход между двумя системами учётных данных, и это решение об авторизации, принимаемое на сервере, а не один токен, который проходит проверку в двух местах. Наборы ключей подписи остаются непересекающимися.
- За создание клиента платит сеть. Экран согласия об этом говорит; здесь это повторено, чтобы никто не узнал об этом из счёта.
- Учётные данные ограничены одной сетью, привязанной при авторизации. За человеком в другую сеть они никогда не переходят.
Когда двум приложениям нужно знать, что они обслуживают одного и того же человека, общим идентификатором служит сеть, в которую допустили их обоих, — а не человек. Это намеренно: на сеть дано согласие, она названа на экране и может быть отозвана, тогда как долговечный идентификатор пользователя не обладал бы ни одним из этих свойств.
Токены
Запланировано.
| Токен | Срок жизни | Примечания |
|---|---|---|
| Токен доступа | 1 час | Привязан по аудитории к одному ресурсу |
| Токен обновления | 90 дней, скользящий | Непрозрачный и ротируемый — каждое использование выводит из оборота предыдущий |
| ID-токен | 1 час | Адресован вашему client_id; никогда не отправляйте его серверу ресурсов |
Токены обновления ротируются, а повторное использование выведенного из оборота токена считается кражей: отзывается всё семейство токенов. Храните самый новый из выданных вам.
Требования к вашему приложению
- PKCE с
S256. Не опционально. - URI перенаправления с точным совпадением, зарегистрированные заранее, только HTTPS. Нативные приложения могут использовать
http://127.0.0.1:/…. - Проверяйте
issв ответе авторизации — именно это защищает от атак типа mix-up. - Проверяйте
audв ID-токене: он должен совпадать с вашимclient_id. - Не предъявляйте API оператора токен входа через URnetwork. Наборы ключей не пересекаются; это не может сработать, и так задумано, а не упущено.
Получение client_id
Выдача проходит проверку, а не открыта всем. Допущенное приложение может обращаться к чужим устройствам, поэтому клиентов проверяют, прежде чем они смогут запрашивать идентичность или доступ к сети. Динамическая регистрация остаётся доступной для областей доступа, относящихся только к MCP, где охват ограничен поиском провайдеров.
Консоли самообслуживания пока нет. Запросите client_id, и мы его выдадим.
Отзыв
Запланировано.
Люди управляют разрешениями на экране подключённых приложений (connected apps) в приложении URnetwork, и отзыв разрешения удаляет созданных им сетевых клиентов. Ваше приложение видит, как обрывается сеанс connect и clientId перестаёт резолвиться, — это отзыв, а не сбой.
Токены доступа живут час, поэтому отзыв вступает в силу в течение часа, а не мгновенно.