# Protection Map: що захистила збірка

HTML-звіт, який показує, що AfterPack зробив із вашим кодом: кожен токен розфарбовано за тим, скільки трансформацій він зазнав.

Source: https://www.afterpack.dev/uk/docs/protection-map

Protection Map є способом перевірити ваш захист: ваш оригінальний вихідний код, у якому кожен токен розфарбовано за тим, скільки трансформацій він зазнав.

```bash
npx afterpack@latest dist/
```

Ви отримуєте таку мапу:

*(live Protection Map demo embed — see https://www.afterpack.dev/protection-map-demo)*

## Як її читати

Токени розфарбовано за оцінкою складності: це те, скільки трансформацій зазнав кожен токен, і саме на це число націлюється [`complexity`](https://www.afterpack.dev/uk/docs/config#complexity). Що червоніший токен, то більше трансформацій він зазнав:

| Колір | Оцінка складності |
| --- | --- |
| Сірий | Складності не додано. Код, який навмисно залишено читабельним, теж сірий. |
| Зелений | Менше 4 |
| Жовтий | Від 4 до 7 |
| Червоний | Від 7 до 10 |
| Темно-червоний | Понад 10 |

Колір показує, скільки застосовано. Виділіть токен, і інспектор покаже, через що пройшла його ділянка: застосовані трансформації, яку частину ділянки вони охоплюють і чому код, що лишився читабельним, лишився таким. Мапа від старішого рушія не має оцінок для окремих токенів і показує весь захищений код одним кольором. Оголошення, яке переписав рушій, наприклад `var` на `let` або функцію на стрілкову, наведено в рядку «Also rewritten». Форматер скасовує такі переписування, тож вони не додають ні складності, ні кольору.

Найсильніша трансформація, що торкнулася токена, визначає його мітку [класу відновлення](https://www.afterpack.dev/uk/docs/reversal-classes), яку показано поруч із його трансформаціями. Це класи [статичного зловмисника](https://www.afterpack.dev/uk/docs/threat-model): вони описують, із чим стикається той, хто читає байти. Міток чотири:

| Мітка | Клас відновлення | Що це означає |
| --- | --- | --- |
| **Збережено** | Немає | Не зачеплено: [сторонні імпорти](https://www.afterpack.dev/uk/docs/config#paths-exclude), публічні експорти, усе, що [виключено](https://www.afterpack.dev/uk/docs/config#paths-exclude) або позначено [`skip`](https://www.afterpack.dev/uk/docs/config#skip). Залишено читабельним, щоб виклики й далі розв'язувалися. |
| **Перейменовано й закодовано** | [поліноміально-ін'єктивний](https://www.afterpack.dev/uk/docs/reversal-classes) | Ідентифікатори перейменовано, [рядки закодовано](https://www.afterpack.dev/uk/docs/config#strings-encode), потік керування сплощено, тотожності злито. Структуру можна відновити, доклавши реальних зусиль; це перемагає AI-пояснювачі та стандартні деобфускатори. |
| **Сплощено й злито** | поліноміально-неін'єктивний | Логіку переписано так, що кілька різних оригіналів зводяться до одного результату, і зловмисник відновлює еквівалентне обчислення, а не ваше. Жодна трансформація, що постачається, сьогодні не досягає цього класу. |
| **Знищено й злито** | деструктивне злиття | Розкладено й злито в межах усього бандла. Статичний читач відновлює еквівалентну програму, а не те, який саме оригінал написали ви. Недоступно; див. нижче. |

Наведіть курсор на токен, щоб побачити застосовані до нього трансформації, згруповані за категоріями (наприклад, сплощення потоку керування), разом із класом, до якого він потрапляє. [Спробуйте в живому демо](https://www.afterpack.dev/protection-map-demo).

Число за кольором є оцінкою складності. Ділянку, яка зазнала менше трансформацій, ніж ви очікували, варто підняти через її [`preset`](https://www.afterpack.dev/uk/docs/config#preset) або позначити [`preset=hard`](https://www.afterpack.dev/uk/docs/config#preset).

> **Колір не є гарантією безпеки**
>
> Захищена ділянка протистоїть статичному читанню: grep, інструментам для AST, «сліпій» LLM. Значення, яке використовує код під час виконання, усе одно доступне для спостереження зловмиснику, який [запускає його в інструментованому середовищі виконання](https://www.afterpack.dev/uk/docs/threat-model#the-boundary). Справді цінні секрети тримайте [на сервері](https://www.afterpack.dev/uk/docs/threat-model#not-a-substitute-for-server-authoritative-validation). Мапа показує, із чим стикається статичний читач, і нічого більше.

## Позначте цінний код

Мапа показує більше трансформацій там, де ви їх запитуєте. Дві [форми директив](https://www.afterpack.dev/uk/docs/directives#writing-one) покривають майже кожен випадок. Вбудована позначка охоплює літерал або вираз у решті свого рядка. Блокова позначка, що стоїть окремо на своєму рядку, відкриває ділянку, яку закриває парний `/* @afterpack end */`; покривається все між ними, зокрема цілі тіла функцій.

```ts
// A single literal — API keys, license secrets, sensitive constants:
const SECRET = /* @afterpack preset=extreme */ "EXPECTED_LICENSE_SECRET";

// A whole function — validators, anti-cheat, payment flow.
// The opener is alone on its line; the matching end closes the block:
/* @afterpack preset=hard */
export function checkLicense(token: string): LicenseClaims | null {
  // ...everything in here is at complexity target 12...
}
/* @afterpack end */

// A span of several statements:
/* @afterpack preset=extreme */
const claims = JSON.parse(atob(payload));
if (claims.secret !== SECRET) return null;
/* @afterpack end */
```

Якщо позначена вами ділянка показує не більше трансформацій, ніж код довкола неї, директива не спрацювала. Зазвичай це означає, що компілятор прибрав коментар раніше, ніж його побачив AfterPack. AfterPack [про це повідомляє](https://www.afterpack.dev/uk/docs/directives#checking-what-was-applied). Повна граматика директив наведена в розділі [Директиви](https://www.afterpack.dev/uk/docs/directives#writing-one); позначки, використані вище, це [`preset=hard`](https://www.afterpack.dev/uk/docs/config#preset) і [`preset=extreme`](https://www.afterpack.dev/uk/docs/config#preset).

## Free проти Pro

Free уже перейменовує й кодує на пресеті за замовчуванням `light`, а починаючи з `medium` ще й сплощує потік керування та зливає тотожності в межах файлу. Усе це залишається в поліноміально-ін'єктивному [класі](https://www.afterpack.dev/uk/docs/reversal-classes): статичний читач відновлює вашу оригінальну структуру ціною реальних зусиль, які доводиться повторювати з кожною збіркою.

[Pro](https://www.afterpack.dev/uk/docs/pro) додає [точкове націлювання на окремі ділянки](https://www.afterpack.dev/uk/docs/directives#what-you-can-set), яке дає змогу розфарбувати саме той десяток функцій, де помилка коштує дорого, а також дві трансформації посилення ([`selfIntegrity`](https://www.afterpack.dev/uk/docs/config#transforms-kind-enabled), [`comparisonHardening`](https://www.afterpack.dev/uk/docs/config#transforms-kind-enabled)). Free добре покриває основну частину реальної кодової бази; Pro потрібен довкола перевірок ліцензій і секретів. Порівняння пліч-о-пліч див. у розділі [Тарифи](https://www.afterpack.dev/uk/docs/tiers).

Класи «Сплощено й злито» та «Знищено й злито» сьогодні не створює жодна трансформація, що постачається. Див. [Класи відновлення](https://www.afterpack.dev/uk/docs/reversal-classes).

## Згенеруйте свою

```bash
npx afterpack@latest dist/
```

Ви отримуєте той самий інтерактивний вигляд, відображений для вашого власного вихідного коду: статичний HTML-файл без входу і без [телеметрії](https://www.afterpack.dev/uk/docs/config#telemetry-enabled), який можна прикріпити до PR. Мапа відображає ваш оригінальний вихідний код, тому за замовчуванням записується лише тоді, коли ваша збірка видала source map, за яким рушій може пройти назад, і не в CI (`CI=true` або `CI=1`). В іншому разі її треба ввімкнути явно: передайте [`protectionMap: { enabled: true }`](https://www.afterpack.dev/uk/docs/config#protectionMap-enabled) у параметрах плагіна, і плагін сам увімкне мапу бандлера. Передайте [`--protectionMap.enabled=false`](https://www.afterpack.dev/uk/docs/config#protectionMap-enabled), щоб її пропустити. Вказуйте на каталог збірки: [Next.js](https://www.afterpack.dev/uk/docs/frameworks/nextjs) пише в `.next/`, [Nuxt](https://www.afterpack.dev/uk/docs/frameworks/nuxt) у `.output/`, більшість бандлерів у `dist/`.

## Де зберігається ваша мапа

[Локальна (Free) збірка](https://www.afterpack.dev/uk/docs/deployment-modes) записує мапу в [`.afterpack/protectionMap.html`](https://www.afterpack.dev/uk/docs/cli#files) на вашій машині і нікуди нічого не надсилає. Каталог має власний `.gitignore`, тож git його ігнорує. CLI відмовляється записувати мапу в шлях, який роздається сервером. Опублікована Protection Map містить увесь ваш вихідний код. Ніколи не публікуйте її.

[Хмарна збірка Pro](https://www.afterpack.dev/uk/docs/deployment-modes) не записує локального файлу. AfterPack зберігає її мапу в [дашборді](https://www.afterpack.dev/uk/docs/dashboard/builds), а коли [`protectionMap.enabled`](https://www.afterpack.dev/uk/docs/config#protectionMap-enabled) увімкнено, збірка після завершення виводить посилання на цю мапу. Мапу створює хмарний рушій, який виконав обфускацію, єдиний рушій, що враховує ваші директиви [`preset=hard`](https://www.afterpack.dev/uk/docs/config#preset), [`preset=extreme`](https://www.afterpack.dev/uk/docs/config#preset) і [`skip`](https://www.afterpack.dev/uk/docs/config#skip), тож це єдина мапа, яка може показати їхній ефект.

> **Збережена мапа містить ваш оригінальний вихідний код**
>
> Protection Map є вашим кодом, розфарбованим. У хмарній збірці Pro вона зберігається на інфраструктурі AfterPack і доступна для читання **кожному учаснику [робочого простору](https://www.afterpack.dev/uk/docs/dashboard/workspaces), якому належить проєкт**. Якщо ваш вихідний код не повинен бути доступним усьому робочому простору, вимкніть її. Див. нижче.

Що саме зберігається:

- **Дані мапи для кожної збірки**: ваш оригінальний вихідний код і метрики для кожного токена, що стоять за кольорами, у Cloudflare R2, зашифровані у стані спокою за допомогою AES-256, разом із рядком підсумкових чисел (покриття, роздування, кількість слабких місць), які дашборд показує на графіках. Ваш обфускований результат не зберігається.
- **В межах одного проєкту**, того, до якого прив'язано [ключ](https://www.afterpack.dev/uk/docs/dashboard/api-keys) збірки.
- **Доступні для читання лише учасникам цього робочого простору.** Не публічні, не індексуються, без посилання для поширення.
- **Зберігаються один рік і для останніх 500 збірок на проєкт, залежно від того, що закінчиться раніше.** Щогодинне завдання видаляє все, що виходить за будь-яку з цих меж. Однорічне вікно дає змогу порівнювати реліз із попереднім. Обмеження у 500 збірок не дає проєкту, який збирається багато разів на день, накопичити копії вихідного коду за цілий рік; для такого проєкту саме це обмеження спрацьовує першим.
- **Збірка, яка не змогла зберегти мапу, натомість залишає примітку** з причиною та відповідними розмірами, але ніколи з вашим кодом і ніколи з назвою файлу. Вона зберігається й видаляється за тим самим графіком, а дашборд показує таку збірку як *не збережено*, а не як збірку, яка ніколи не запускалася.
- **Коли це вікно минуло, дашборд так і пише.** Примітки й мапи застарівають разом; історія ваших збірок ні. Збірка, старша за наведений вище строк зберігання, показується як *немає запису*.

### Як це вимкнути

Зберігання мап увімкнене за замовчуванням, для кожного проєкту. Адміністратор [робочого простору](https://www.afterpack.dev/uk/docs/dashboard/workspaces) може вимкнути його в налаштуваннях проєкту. Після цього нові хмарні збірки цього проєкту нічого не генерують і не зберігають; уже збережені мапи застарівають за наведеним вище строком зберігання, а не зникають одразу. Збірок Free це в жодному разі не стосується: їхня мапа записується локально і ніколи не звертається до мережі.

**Ваші [графіки в дашборді](https://www.afterpack.dev/uk/docs/dashboard/builds) продовжують працювати.** Вимкнення зупиняє зберігання вашого вихідного коду. Воно не зупиняє запис того, що виміряла збірка. Покриття, роздування, складність і час збірки не містять коду, і вони й далі записуються та показуються на графіках для проєкту з вимкненим захопленням. Єдиний виняток — кількість слабких місць, бо її рахують усередині збереженої мапи. Обфускований результат не змінюється.

Збережена мапа є єдиним, що AfterPack зберігає постійно і що містить ваш вихідний код. Усе інше щодо [хмарної збірки](https://www.afterpack.dev/uk/docs/cloud-api) залишається в пам'яті на час одного запиту. Див. [Конфіденційність і обробка даних](https://www.afterpack.dev/uk/docs/privacy).

## Далі

- [Класи відновлення](https://www.afterpack.dev/uk/docs/reversal-classes): три класи, що стоять за цими мітками, для кожної трансформації.
- [Найкращі практики](https://www.afterpack.dev/uk/docs/best-practices): патерни для позначення правильних ділянок.
- [Конфігурація](https://www.afterpack.dev/uk/docs/config): граматика директив, правила для окремих файлів, пресети.
- [Як працює AfterPack](https://www.afterpack.dev/uk/docs/concepts): три класи відновлення детально.
- [Модель загроз](https://www.afterpack.dev/uk/docs/threat-model): вісь «статичний проти динамічного», на яку спираються ці мітки.
- [Конфіденційність і обробка даних](https://www.afterpack.dev/uk/docs/privacy): що зберігає хмарна збірка, як довго і хто може це читати.
- [Директиви](https://www.afterpack.dev/uk/docs/directives): кожна позначка, яку можна поставити перед ділянкою.
- [Pro](https://www.afterpack.dev/uk/docs/pro): що відкриває позначення окремих ділянок і збережені мапи.
- [Живе демо](https://www.afterpack.dev/protection-map-demo): той самий вигляд на зразковому вихідному коді, нічого не треба встановлювати.
