t27.aiEnglish

Секреты остаются вне репозитория и промпта

Вы узнаете

Почему имя секрета может жить в репозитории, а его значение нет: ни в файле, ни в промпте.

Секрет — это значение, которое что-то открывает, например токен бота. Код называет его, BOT_TOKEN, и никогда не хранит. Значение живёт в файле .env на вашей машине, а git велено этот файл игнорировать. В репозитории лежит только .env.example с выдуманной заглушкой. В secrets_out.t27 файл с секретом никогда не входит в то, что сохраняет git, и то же верно для сообщения агенту: пишите имя секрета, а не его значение. Секрет, который хоть раз был сохранён или вставлен в сообщение, считают утраченным и заменяют.

Попробуйте

Переключите файл с настоящими настройками на «сохранять» и прочитайте тревогу. В кадре со спецификацией найдите тест, который падает, когда TRACKED говорит, что файл с настоящими настройками сохранён, и строку, которую вы изменили бы, чтобы подложить это.

Открыть интерактивный урок →

Secrets stay out: tick which files git saves ↗

Four files of a small bot project: switch each between saved and ignored and see the alarm when a file with a secret is saved. Only a made-up placeholder is used.

specs/vibecoding/secrets_out.t27

// SPDX-License-Identifier: Apache-2.0
; specs/vibecoding/secrets_out.t27 -- lesson "Secrets stay out of the repository and the prompt"
; of the course Vibecoding from zero
; The one idea: a secret has a name in the code and a value only on your machine. The repository
; holds the name (BOT_TOKEN) and an example file with a made-up placeholder; the real value sits in
; a file the repository ignores, and it is never pasted into a prompt either. The placeholder below
; is invented for this lesson and opens nothing. ASCII only (L3), English only (LANG-EN).
; phi^2 + 1/phi^2 = 3 | TRINITY

module vc_secrets_out;

pub const SECRET_NAME : str = "BOT_TOKEN";
pub const PLACEHOLDER : str = "your-token-goes-here";

; Four files of a small project: the code, the example settings, the real settings, the notes.
; HOLDS_SECRET is 1 where a file carries a real value; TRACKED is 1 where git saves the file.
pub const FILE_NAMES : [4]str = ["bot.t27", ".env.example", ".env", "README.md"];
pub const HOLDS_SECRET : [4]u8 = [0, 0, 1, 0];
pub const TRACKED : [4]u8 = [1, 1, 0, 1];

; Prompts you send to an agent: 1 where the text carries a real secret value.
pub const PROMPT_HOLDS_SECRET : [3]u8 = [0, 0, 0];

; A file is safe when it does not both hold a secret and get saved by git.
pub fn leaks(holds: u8, tracked: u8) -> u8 {
    return holds * tracked;
}

; Negative control: plant the bug (TRACKED = [1, 1, 1, 1], the real .env saved by git) and the
; test below turns red.
test no_file_holds_a_secret_and_is_tracked {
    assert HOLDS_SECRET[0] * TRACKED[0] == 0;
    assert HOLDS_SECRET[1] * TRACKED[1] == 0;
    assert HOLDS_SECRET[2] * TRACKED[2] == 0;
    assert HOLDS_SECRET[3] * TRACKED[3] == 0;
}

test the_example_file_is_saved_and_the_real_one_is_not {
    assert FILE_NAMES[1] == ".env.example";
    assert TRACKED[1] == 1;
    assert FILE_NAMES[2] == ".env";
    assert TRACKED[2] == 0;
}

test no_prompt_carries_a_secret {
    assert PROMPT_HOLDS_SECRET[0] == 0;
    assert PROMPT_HOLDS_SECRET[1] == 0;
    assert PROMPT_HOLDS_SECRET[2] == 0;
}

test the_name_is_in_the_code_and_the_value_is_not {
    assert SECRET_NAME == "BOT_TOKEN";
    assert PLACEHOLDER == "your-token-goes-here";
}

Открыть спеку урока в плеере ↗

Все уроки