Security

    How to securely deliver a config file to a developer

    Split settings from secrets, send the secret values through a one-time link or an attachment that burns after one download, and keep the .env out of git.

    LinkPilot Team · The people who build and run LinkPilot at TetraCore, LLC · About LinkPilot

    A new developer joins, or a contractor starts, and the first thing they need is the .env that makes the project run. That file is usually a mix of harmless settings and the most sensitive values the team owns, which is why it so often ends up in a direct message or an email attachment titled "config".

    To securely deliver a config file to a developer, treat it as two things: settings, which can travel anywhere, and secrets, which travel once through a channel that keeps no copies. This guide covers how to split the two, how to send the secret half, and what to tell the developer so the file stays safe after it lands.

    Read the file as if every line were public

    Open the file and sort each line into one of two groups.

    • Settings: log levels, ports, feature flags, non-production endpoints, public client IDs. These belong in the repository as an example file and can be sent any way you like.
    • Secrets: database passwords, API keys, signing secrets, private keys, OAuth client secrets, anything that grants access. Search for PASSWORD, SECRET, TOKEN, KEY and PRIVATE, and then read the rest, because a connection string with the password embedded does not announce itself.

    Then ask what the developer is doing. Local development against staging needs the staging values. It does not need production keys, and it does not need the payment provider's live key just because the file happens to contain one.

    Keep secrets out of the committed file

    The committed .env.example documents every variable with a placeholder. The real values are injected at runtime from the environment, a secrets manager or the platform's own secret store. That pattern means the file you deliver is only the secret values, and the developer's local copy is the only place they exist together.

    # .env.example (committed)
    DATABASE_URL=postgres://app:CHANGE_ME@staging-db.internal:5432/app
    STRIPE_SECRET_KEY=sk_test_CHANGE_ME
    SESSION_SECRET=CHANGE_ME
    LOG_LEVEL=debug
    

    Add .env to .gitignore before anyone has a real one, and consider a pre-commit hook such as gitleaks so a stray commit fails fast.

    Give the developer their own credentials where you can

    A handoff is also a chance to stop sharing. If the database supports individual users, create one for the developer with the permissions their work needs and an expiry date. If the API offers restricted keys, issue one in their name. The contractor database login guide covers that pattern. Credentials made for one person can be removed for one person.

    How to deliver the secret values

    Two routes work, and both avoid leaving the file in a message.

    Paste the secret lines into a one-time link. Open the secret link tool, paste only the lines that contain secrets, and create the link. The text is encrypted in your browser before it is stored, the stored copy is destroyed the first time the link is opened, and the link expires after one hour, 24 hours or seven days if nobody opens it. Up to 10,000 characters fit without an account, which covers most .env files several times over.

    Attach the whole file to a secret link. From a signed-in LinkPilot account you can attach up to three files of 9 MB each to a secret. Each file is encrypted in your browser with a key derived from the secret's own key, so the server never holds the plain file, and the attachment is deleted after the single download. This is the better route when the file has to arrive byte-for-byte, for example a JSON service account file or a keystore.

    Either way:

    1. Verify the developer through the hiring or contract channel, not the address that asked for the file.
    2. Set the expiry to the window they will actually use. One hour if they are waiting, a day if they are in another time zone.
    3. Set the view limit to one.
    4. Add a passphrase on a Pro account for production values, and send it by a different channel.
    5. Send the link with a one-line note of what it is and where the file belongs. Send the non-secret settings separately or point at the example file in the repo.

    A vault invitation is the better route when the developer is a permanent hire and your team already runs a secrets manager with per-developer access. Use the one-time link for the gap before that is set up, and for anyone who will never be in the vault.

    Tell the developer where it belongs

    A clean delivery can still end badly if the file lands in a shared folder. Send these with the connection details:

    • Save it as .env in the project root and nowhere else. Check it is covered by .gitignore before the first commit.
    • Do not paste values into tickets or chat to ask whether they are right. Report a missing or invalid variable by name only, and the sender will issue a fresh value.
    • Rotate on departure. When the engagement ends, the values in that file get rotated. Say so up front, so nobody is surprised.

    Confirm, then clean up

    Ask the developer to confirm the filename, the environment and a non-secret marker, such as a version comment in the first line. If a one-time link reports that it was opened before they got to it, treat every value in it as exposed and rotate.

    When the handoff is complete, revoke any link that was never opened, remove any temporary storage copy you made, and record who received which environment's values and when. The record is the audit trail. The file itself should exist only on the machine that needs it.

    Tools for this article

    Frequently asked questions

    LinkPilot sends a secret link that is gone after it is opened.

    Encrypted in your browser, revealed once, then destroyed. No account needed.

    Create a secret link

    Read next