code.view: false in the manifest, hide the variables that belong to you with env_hidden, and send a use link: the client previews it, fills in their own answers and gets an app that starts, stops, logs and snapshots like any other, with the code sealed. In this tutorial you deliver a bot to a client this way.
The platform enforces the seal on its own API, in every route that reads or changes files and code, not only in the dashboard. It does not make your code secret from someone who controls the machine it runs on or from the Vertra team, and it cannot protect you from a flaw in your own code that serves files. Read Permissions for the full list of guarantees.
Before you start
A working private code template, such as the one from the first tutorial. Open and closed templates share the same structure, so you only change the permissions.
A plan that can create private templates (see Plans and limits).
A second account you can sign in to. It is the only way to see the preview and the closed app exactly as the client does.
What the client can and cannot do
Databases are never closed: the client has full access to their data, as they would on any database they own. Keep anything that must stay out of the client’s reach in your own code and variables, not in the database.
Step by step
1
Decide what is yours and what is the client's
Split the configuration in two. What the client provides (their Discord token) becomes a question. What you provide (a key for a service you pay for, or a license) becomes a hidden variable: injected into the app, never returned by the API and never shown in the panel. In this tutorial the bot reads
VENDOR_API_KEY, which is yours.2
Write the closed manifest
Start from the manifest of the first tutorial and change three things: set
code.view to false, add the hidden variable and leave out everything a closed template cannot allow.vertracloud.template.yaml
permissions.code.view: falseis what closes the template. The platform derives the rest: no free variables, no command editing, no terminal, no save as template, no detach, no code deploy.env_hiddenlists keys ofenv. The value is written in the manifest only so the platform can store it; after the template is created, the stored manifest no longer carries it.- What you must leave out.
code.edit: true,env.add: true,commands.edit: trueandshare.full_copy: trueare refused on a closed template withinvalid_permissions, because each one would hand the code or its secrets back. Do not list them at all. - Placeholders still work. The client’s answers and the generated secrets go into the app as usual; the code you hide is the only thing the client cannot read.
Closed code and
env_hidden only exist in private templates, and env_hidden only in a closed one (a validator error invalid_permissions otherwise). A template in the public catalog always shows its code, and the catalog refuses code.view: false and env_hidden with forbidden_in_public.3
Validate
code: { view: false, edit: true } and the finding is permissions.code.edit with code invalid_permissions (“A closed template cannot let users edit its code”). Remove the edit line again.4
Create the template
null.5
Create the use link
A use link gives the client the right to create apps from the template, with their own copy of the image when the template uses one. For a client, make it single-use and short-lived:The CLI prints the token once. Copy it and send it to the client right away; afterwards you can only see the end of it and revoke it. In the panel the same thing is Templates, My templates, the template, Share links, Create link.There is also a full-copy link, which gives the receiver a template of their own with code and image. It is not available here: a full-copy link shows the code, so on a closed template the panel says “Unavailable: closed template” and the API refuses the manifest combination with
invalid_permissions.6
Know what the client sees
The link opens a preview page before anything is created. The client sees the author, the version, what will be created (services, minimum memory, required plan, image slots), a Not verified by Vertra badge and this notice:
Closed code. The values you fill in (for example, your OpenAI key) go to code you cannot see. You are trusting the author.The client then signs in, chooses where to create the app and answers the questions. The preview has a Report button for anyone who finds the template abusive. On the app, the client sees the Closed template tag and the explanation that the code belongs to the author and which actions remain open.Be honest with your client about the trust involved: the notice above is shown to them by design.
7
Update and revoke
To fix something, raise Revoking stops new creations and stops offering updates. What the client already created keeps running: it belongs to them, and you can never stop, delete or read anything in their account.
version and run vertra template create --template support-bot --changelog "Describe the change". The client sees New version available and updates when they choose, with a safety snapshot taken first; an update is never automatic. When the contract with the client ends, revoke the link:Troubleshooting
Next steps
- Closed templates for those who use them: the client’s side of the same page.
- Receive a template by link: the preview, the image copy and the report flow.
- Share links: use links versus full-copy links, limits and revocation.
- Permissions: every combination and what each one locks.
- Best practices: where to keep data in a closed template.
- Next tutorial: from a private template to the public catalog.