Файлы проекта и логические бакеты
Создавайте бакеты, загружайте и выдавайте файлы, настраивайте правила и анонимные формы.
Что это
Логический бакет — отдельное пространство файлов внутри проекта и одного окружения. Он хранит понятный адрес и правила загрузок, но не раскрывает устройство облачного хранилища или служебные ключи.
На странице «Файлы» можно создавать, просматривать, настраивать и удалять логические бакеты, загружать файлы и явно включать профили анонимной загрузки для доверенных адресов сайтов. Те же действия доступны через Platform API.
Публичная форма может получить защищённую session, загрузить один файл по короткой POST-форме и завершить проверку без Platform или Runtime token в браузере.
Backend приложения может безопасно и повторяемо привязать завершённую anonymous session к одному заказу через Runtime SDK. Public status, проверка содержимого и выдача файла выполняются через короткую защищённую ссылку.
Когда использовать
- Нужно заранее разделить файлы production и development.
- Для разных групп файлов нужны разные ограничения размера или форматов.
- Нужно загрузить файл без передачи платформенного токена сервису хранения.
- Нужно принять файл из формы заказа или лендинга без привилегированного токена в браузере.
Перед началом
- Раздел «Файлы» включается для организаций поэтапно. Если пункта нет в навигации проекта или прямая ссылка показывает страницу 404, организация ещё не подключена к бете; дополнительных действий от пользователя не требуется.
- Выберите проект и окружение.
- Для просмотра нужна роль участника платформы, разработчика или администратора проекта.
- Для создания, изменения и удаления нужна роль разработчика или администратора проекта.
- Для загрузки подходит роль участника платформы, разработчика или администратора проекта.
- Профили анонимной загрузки создают, изменяют и отключают разработчики и администраторы проекта; участник платформы может их просматривать.
- Обычный максимальный размер одного файла — 100 МБ.
- Для обычной, не анонимной PUT-загрузки заранее вычислите SHA-256 файла в нижнем регистре.
Как управлять файлами в интерфейсе
- Откройте проект, выберите окружение в меню слева и перейдите в раздел «Файлы».
- Нажмите «Создать бакет». Укажите короткий адрес, доступ по умолчанию, максимальный размер и при необходимости правила форматов и хранения. Адрес после создания не меняется.
- Выберите бакет слева и нажмите «Загрузить файл». Перетащите один файл в окно или выберите его, задайте доступ и подтвердите загрузку. Индикатор показывает подготовку, передачу и проверку. При ошибке нажмите «Повторить загрузку»: выбранный файл и параметры сохраняются. Если сменить файл или доступ, начинается новая попытка.
- После передачи дождитесь готовности в списке. Уведомление «Файл передан на проверку» ещё не означает, что его можно скачать. Пустой файл, превышение размера и запрещённый формат отмечаются до отправки.
- Используйте поиск по названию, фильтр типа и сортировку по дате, имени или размеру. Нажмите название файла, чтобы открыть сведения: размер, доступ, статус, дату загрузки и срок хранения. Для готовых публичных изображений доступен предпросмотр; остальные готовые файлы можно скачать.
- Для готового публичного файла скопируйте стабильную ссылку. Короткая ссылка для скачивания запрашивается при нажатии и открывается сразу.
- Нажмите «Использование», чтобы открыть данные хранения и доставки за расчётный период организации. Хранение показывается по ставке 8 ₽ за ГиБ·месяц как предварительная оценка. Доставка пока отображается справочно по будущей ставке 4 ₽ за ГиБ без списания. Фактические расходы смотрите в разделе «Баланс и расходы».
- Откройте «Настройки бакета», чтобы изменить ограничения. Если закрыть изменённую форму, появится выбор: продолжить редактирование или закрыть без сохранения. При ошибке сохранения введённые значения остаются в форме.
- Для удаления файла подтвердите действие в отдельном окне. Удалить бакет можно только после удаления его файлов и отключения активных профилей; интерфейс сначала проверяет эти условия.
Участник платформы может просматривать и загружать файлы. Управлять бакетами, удалять файлы и изменять профили могут разработчики и администраторы проекта, а также владелец организации.
Приватные файлы выдаёт backend приложения, файлы для пользователей — активная сессия пользователя приложения, командные — участник проекта, публичные — любой получатель ссылки на конкретный готовый файл. Публичного списка файлов нет.
Как управлять через API
- Откройте Swagger вашего Agnostic API и авторизуйтесь токеном Platform Auth.
- В разделе Files выберите создание бакета для нужного проекта.
- Укажите окружение и короткий адрес латиницей, цифрами и дефисами.
- Выберите режим доступа по умолчанию: приватный, для вошедших пользователей приложения, для команды проекта или публичный.
- При необходимости добавьте разрешённые и заблокированные MIME-типы, уменьшите максимальный размер файла и задайте срок хранения готовых файлов.
- Используйте операции Files для просмотра или изменения бакета. Всегда передавайте то же окружение, в котором он создан.
Как включить профиль анонимной загрузки
- Создайте profile операцией
POST .../buckets/{bucketId}/anonymous-upload-profilesв нужном проекте и окружении. - Укажите только точные HTTP/HTTPS origins без пути, query, fragment и wildcard. Например,
https://shop.example.com, но неhttps://shop.example.com/upload. - Задайте разрешённые MIME-типы и лимиты одного файла, количества файлов и общего размера session. Они не могут быть шире правил бакета.
- Выберите claim policy:
ready_onlyдля обязательной готовности всех файлов илиallow_processing, если заказ можно принять во время проверки. - Проверьте ответ: CAPTCHA всегда обязательна, а начальный доступ всегда приватный. Для отключения profile используйте DELETE; повторное отключение безопасно.
Стартовые значения: до 15 МБ на файл, пять файлов и 50 МБ на session, session TTL 30 минут, grant TTL 5 минут, хранение незаявленных файлов до 24 часов. Grant TTL можно выбрать только от 2 до 5 минут.
Публичный идентификатор profile не является секретной ссылкой и сам по себе не разрешает загрузку. Загрузку разрешает только короткая session после CAPTCHA и проверки точного origin.
Как принять файл из публичной формы
- Выберите способ создания session. Для управляемого варианта браузер вызывает
POST /api/v1/files/public/anonymous/profiles/{publicId}/sessionsс точным заголовкомOriginи токеном CAPTCHA. Для BFF-варианта backend приложения вызываетPOST /api/v1/runtime/files/buckets/{bucketId}/anonymous-upload-sessions; Runtime token остаётся только на backend и никогда не попадает в браузер. - Получите
sessionTokenиclaimToken. Они показываются один раз. Держите их только в памяти текущего сценария, не помещайте в URL, логи, аналитику или постоянное хранилище браузера. - Для каждого файла вызовите
POST /api/v1/files/public/anonymous/profiles/{publicId}/grants. ПередайтеsessionTokenкак Bearer token, тот же точныйOrigin, имя, MIME-тип, размер и уникальныйidempotencyKey. - Создайте
multipart/form-dataиз всех выданныхfieldsбез изменений и добавьте ровно одинfileпоследней частью. Отправьте форму наuploadUrl. Не добавляйте redirect и не меняйте приватный режим, MIME-тип, ключ или размер. - После ответа
204вызовитеPOST /api/v1/files/public/anonymous/profiles/{publicId}/uploads/{uploadId}/completeс теми жеOriginи BearersessionToken. Считайте файл готовым только после ответаstatus: ready. - Если запрос проверки оборвался, прочитайте безопасный статус через
GET /api/v1/files/public/anonymous/profiles/{publicId}/uploads/{uploadId}/statusс теми же Origin и Bearer token. Ответ содержит толькоprocessing,readyилиrejectedи публичные идентификаторы файла.
Grant действует от 2 до 5 минут и разрешает только один файл точного размера на запрос. Повтор create с тем же idempotencyKey и теми же параметрами безопасен; использование ключа с другими параметрами отклоняется. Не переиспользуйте уже отправленную форму.
Complete сверяет выданную загрузку, фактический размер и целостность байтов, определяет MIME-тип по содержимому и применяет правила бакета и profile, затем переносит файл в неизменяемое закрытое хранилище. Его можно безопасно повторить с теми же параметрами: после успеха API вернёт тот же результат. Если файл изменился во время проверки, complete отклонит загрузку; создайте новую session и не пытайтесь продолжить со старой. ready на этом шаге подтверждает фактический формат, правила содержимого, целостность, malware/archive проверку и неизменяемое закрепление файла.
Как привязать session к заказу
- Сначала создайте заказ или другой business object в backend приложения.
- На server-side вызовите
agnostic.storage.bucket('order-files').anonymousUploads.claim(...)с capabilityfiles.write. - Передайте полученный один раз
claimTokenкакtoken, ссылку на созданный заказ какexternalRefи стабильныйidempotencyKey. Для повторной попытки после сбоя используйте те же три значения. - Сохраните только возвращённые Files handles. Не принимайте отдельные
fileIdиз browser и не смешивайте их со списком из claim response.
Exact retry возвращает тот же результат. Попытка повторно привязать session к другому заказу или использовать тот же idempotency key для другой session отклоняется. Handle ready уже прошёл current complete-проверку; processing означает, что заказ привязан, но файл ещё обрабатывается. Claim token и Runtime token должны оставаться на backend: не помещайте их в URL, логи, аналитику или browser storage.
Как загрузить файл
CSV загружайте с MIME-типом text/csv и кодировкой UTF-8. Бакет должен разрешать этот тип. Проверка формата отклоняет бинарные данные и запрещённые управляющие символы; дальнейший импорт отдельно проверяет весь CSV, его структуру и значения. Для импорта через Agent выберите доступ team, дождитесь готовности файла и укажите его название и окружение в запросе.
- Создайте upload session операцией
POST .../buckets/{bucketId}/uploads, передав имя файла, MIME-тип, точный размер, SHA-256, режим доступа и уникальныйidempotencyKey. - Получите
uploadUrl,uploadUrlExpiresAtиrequiredHeaders. Отправьте одинPUTс исходными байтами и всеми выданными заголовками без изменений. Размер HTTP-клиент выставит по телу автоматически; вручную добавлятьContent-Lengthне нужно. Не добавляйте токен Platform Auth к этой ссылке. - Вызовите
POST .../uploads/{uploadId}/completeв том же проекте, бакете и окружении. Complete можно безопасно повторить: он вернёт сохранённый результат.
Ссылка на загрузку обычно действует 10 минут, а session — 15 минут. Не публикуйте ссылку и обязательные заголовки, не сохраняйте их в логах и не пытайтесь использовать повторно. Перезапись уже загруженных байтов отклоняется.
Что дальше
Бакет сразу появляется в выбранном окружении. Один и тот же адрес можно использовать в другом окружении того же проекта, и это будут разные изолированные бакеты.
Для обычной PUT-загрузки complete возвращает metadata с фактическим размером и SHA-256 только после malware/archive проверки и immutable promotion. Для anonymous POST complete возвращает минимальный ready-result; загрузку можно привязывать к заказу. После проверки access policy можно получить короткую ссылку на скачивание.
Раздел может включаться поэтапно для выбранных организаций. Если «Файлы» ещё не доступны в проекте, не пытайтесь обходить ограничение прямым доступом к облачному хранилищу: обратитесь к владельцу workspace и дождитесь включения возможности. Доставка пока учитывается только для проверки качества измерений и не создаёт списаний.
Как проверить доступ к готовому файлу
Режим доступа выбирается при загрузке и открывается только через подходящую identity boundary:
private— backend с Runtime token и capabilityfiles.read; файл должен
принадлежать тому же Runtime subject после claim;
authenticated— активная App User session того же realm, проекта и
окружения;
team— участник того же проекта через Platform Auth;public— проверка одного конкретногоfileIdбез авторизации.
Операция access возвращает безопасную metadata и подтверждение решения, а операция download — ссылку на конкретную версию сроком 1–5 минут. Для public можно сохранить стабильный адрес GET /api/v1/files/public/objects/{fileId}: он повторно проверяет статус и перенаправляет на новую короткую ссылку. Публичного списка файлов нет. Файл не откроется, пока он не завершил проверку, после истечения срока хранения или после удаления; несовпадение проекта, окружения, владельца или режима также закрывается отказом. После удаления новые ссылки не выпускаются, а ранее выданные прекращают работать не позднее пяти минут. HTML, SVG и JavaScript скачиваются как вложение.
Для команды список и карточка объектов доступны в Platform API внутри project + environment + bucket. Администратор может отдельно выполнить break-glass для одного объекта; это действие всегда аудируется и не превращает его в обычный публичный доступ.
Если после загрузки через интерфейс нужно сверить файл с исходным снимком, откройте список объектов бакета через Platform API и карточку нужного объекта. Карточка содержит file ID, фактический размер, SHA-256 и выбранный режим доступа. Сверьте все четыре значения, прежде чем связывать файл с записью приложения. Приватный файл, загруженный участником команды через интерфейс, не принадлежит Runtime identity API-сервиса и не станет доступен ему только от добавления file ID в запись приложения. Такой пробный объект оставьте без связи и удалите после успешной загрузки через Runtime.
Удаление готового объекта через Platform API сразу скрывает его из list, detail и access и закрывает интервал хранения. Физические байты удаляются повторяемым cleanup не позднее чем через 24 часа; временная ошибка хранилища не возвращает логически удалённый файл в доступ.
Как учитывается хранение
Готовый обычный файл учитывается по ставке 8 ₽ за GiB·месяц пропорционально точному размеру и времени хранения. Для anonymous upload отсчёт начинается только после claim; проверенный, но ещё не привязанный к заказу файл не тарифицируется. Logical delete прекращает учёт сразу, даже если физическая очистка завершится позднее.
Доставка файлов пока измеряется в теневом режиме. Цена 4 ₽ за GiB показана как будущая ставка, но реальные списания за delivery выключены до отдельного подтверждения полноты журналов доставки и финансового gate.
Адрес и окружение бакета после создания не меняются. Если они выбраны неправильно, удалите пустой бакет и создайте новый. Удалённый пустой бакет скрывается сразу, после чего его адрес можно использовать снова.
Частые проблемы
| Проблема | Что сделать |
|---|---|
| Бакет не найден | Проверьте проект и окружение. Бакет из другого окружения намеренно не открывается. |
| Адрес уже занят | Выберите другой адрес или проверьте, не создан ли бакет в том же окружении. |
| Правило форматов отклонено | Уберите MIME-тип, который одновременно указан как разрешённый и заблокированный. |
| Нельзя удалить бакет | Сначала удалите его файлы и отключите активные профили анонимной загрузки. Автоматическое каскадное удаление не выполняется. |
| Нельзя изменить настройки | Попросите администратора проекта выдать роль разработчика или администратора. |
| Ссылка на загрузку истекла | Пока session активна, повторите create с тем же payload и idempotencyKey, чтобы получить новую ссылку. После files_upload_expired создайте новую session с новым ключом. |
| PUT отклонён | Передайте исходные байты и все requiredHeaders без изменений; повторная запись запрещена. |
| Размер не совпал | Повторите загрузку с точным размером файла и новой session. |
| SHA-256 не совпал | Не продолжайте обработку: пересчитайте SHA-256 исходного файла и создайте новую session. |
| Загрузка не найдена | Проверьте project, environment, bucket и uploadId; идентификаторы из другого scope намеренно не открываются. |
| Origin profile отклонён | Передайте точный http:// или https:// origin без пути, query, fragment, credentials и wildcard. |
| Лимиты profile отклонены | Уменьшите размер файла до лимита бакета, проверьте общий размер и оставьте только разрешённые бакетом MIME-типы. |
| Profile отключён | Создайте новый profile или используйте активный; отключённый profile нельзя изменить. |
| Session не создана | Проверьте точный Origin, CAPTCHA и активность profile. При временной недоступности защиты повторите запрос позже. |
| Слишком много запросов | Подождите минуту и не создавайте новую session или grant для каждой попытки повторного рендера формы. |
| POST-форма отклонена | Передайте все выданные поля без изменений, один файл последней частью и не добавляйте redirect. |
| Public complete отклонён | Не продолжайте claim старой загрузки. Проверьте exact Origin, sessionToken, фактический формат, размер и MIME-тип; при подмене типа или ошибке целостности создайте новую session. |
| Runtime capability отсутствует | Выпускайте BFF token только для backend сервиса с правом записи Files; не заменяйте его Platform token и не отправляйте в браузер. |
| Claim отклонён | Проверьте, что upload завершил server-side complete verification, Runtime token относится к тому же проекту и окружению, а повтор использует те же externalRef и idempotencyKey. |
| Доступ к файлу отклонён | Проверьте режим access, identity boundary, проект, окружение, Runtime owner и готовность проверки. Удалённый, просроченный или ещё обрабатываемый файл намеренно закрыт. |