Profiles
A profile answers one question: for this kind of project, which plugins, which permission rules and which enforcement level? It is a single JSON file, applied with one command.
foundry profile # listfoundry profile oss-library # applyThe five profiles
Section titled “The five profiles”| Profile | Plugins | Enforcement | Index budget | Chosen because |
|---|---|---|---|---|
angular-spring-enterprise |
core, dev, quality, ops, pmo, legal | gate |
4000 | A full-stack enterprise product carries CI, database migrations and production config that must not change silently, plus GDPR and accessibility duties that are not optional. |
oss-library |
core, oss, research, quality, dev | gate |
3000 | A public library lives or dies on governance and documentation. LICENSE and NOTICE are protected because changing them has legal consequences for every downstream user. |
pa-italia |
core, legal, dev, quality, pmo, oss, economics | gate |
5000 | Italian public-sector software must produce an audit trail. Accessibility is a legal obligation, not a quality goal, and ADRs are evidence for procurement. The largest index budget of the five, because compliance context is worth carrying. |
startup-mvp |
core, dev, economics, research | warn |
2500 | Speed matters more than ceremony, but the mistakes that are not recoverable by moving fast — leaked secrets, destroyed history — still stop you. |
full |
all twelve | gate |
6000 | For exploring Foundry. In a real project a narrower profile keeps routing cheap. |
Permissions each profile sets
Section titled “Permissions each profile sets”| Profile | Pre-approved | Asks first | Denied |
|---|---|---|---|
angular-spring-enterprise |
mvn, ./mvnw, gradle, ./gradlew, npm run, npx ng, read-only git, Read/Glob/Grep |
git push, docker push, kubectl apply, terraform apply |
reading .env*, **/secrets/**, *.pem, *.p12 |
oss-library |
npm run, npm test, npx, gh issue, gh pr, read-only git, Read/Glob/Grep |
npm publish, gh release, git push, git tag |
reading .env* |
pa-italia |
Read/Glob/Grep, read-only git |
git push, gh release |
reading .env*, **/dati-personali/** |
startup-mvp |
npm, npx, all of git, Read/Glob/Grep, Write, Edit — with defaultMode: acceptEdits |
git push |
reading .env* |
full |
Read/Glob/Grep only |
git push |
reading .env* |
Protected paths each profile adds
Section titled “Protected paths each profile adds”protectedPaths do not deny a write; they escalate it to you for confirmation.
| Profile | Protected |
|---|---|
angular-spring-enterprise |
.github/workflows/**, **/*.lock, package-lock.json, **/src/main/resources/db/migration/**, **/application-prod.* |
oss-library |
.github/workflows/**, **/*.lock, package-lock.json, LICENSE, NOTICE |
pa-italia |
.github/workflows/**, **/*.lock, **/accessibility-statement*, docs/adr/** |
startup-mvp |
.github/workflows/**, **/*.lock |
full |
the built-in default: .github/workflows/**, **/*.lock, package-lock.json, db/migrations/** |
What applying a profile actually changes
Section titled “What applying a profile actually changes”foundry profile <id> touches exactly two files.
.claude/settings.json — merged, never replaced:
extraKnownMarketplaces.foundryis set to the GitHub sourcefedcal/foundry.enabledPluginsgains<plugin>@foundryfor each plugin in the profile, as a set union.permissions.allow,.askand.denygain the profile’s entries, as set unions.permissions.defaultModeis overwritten if the profile declares one.
.foundry/config.json — rewritten as the current effective configuration merged with the
profile’s foundryConfig. Keys the profile does not mention keep their current values.
Then it prints the plugin list and reminds you to restart or run /reload-plugins.
What it does not do
Section titled “What it does not do”- It does not install or download plugins. It records which plugins should be enabled; the marketplace still has to be reachable.
- It never removes anything. Permissions and enabled plugins are merged in, so switching from
fulltostartup-mvpleaves the other eight plugins enabled. To narrow, edit.claude/settings.jsonby hand. foundry profile <id>appliesplugins,permissionsandfoundryConfig, then printsnotes,recommendedMcpServersandjurisdictionPacksfor you to act on. Those three are advice, not automation: no MCP server is installed and no jurisdiction pack is enabled for you.
Write your own
Section titled “Write your own”Profiles are files under profiles/ in a checkout of the Foundry repository. foundry profile
resolves that directory three levels above the CLI (bin/../../../profiles), so a custom profile
must live in the same checkout as the installed plugin. There is no user-level profile directory,
and no way to point the command elsewhere.
Create profiles/data-platform.json:
{ "id": "data-platform", "name": "Data platform", "description": "Batch and streaming pipelines: schema changes are the risk, not the UI.", "plugins": ["foundry-core", "foundry-dev", "foundry-quality", "foundry-ops"], "foundryConfig": { "enforcement": "gate", "indexTokenBudget": 3500, "protectedPaths": [ ".github/workflows/**", "**/*.lock", "dbt/models/**/schema.yml", "airflow/dags/**" ] }, "permissions": { "allow": ["Bash(dbt:*)", "Bash(python -m pytest:*)", "Read(**)", "Glob(**)", "Grep(**)"], "ask": ["Bash(dbt run:*)", "Bash(airflow dags trigger:*)", "Bash(git push:*)"], "deny": ["Read(./.env)", "Read(./.env.*)"], "defaultMode": "default" }}id, description and plugins are the three fields the CLI requires: id and description are
printed by foundry profile with no argument, and plugins is mapped over unconditionally, so a
profile without it throws rather than failing cleanly. foundryConfig and permissions are
optional.
Apply and verify:
foundry profile data-platformfoundry doctorTwo rules worth holding to when you design one. Put a path in protectedPaths when a wrong change
is expensive but sometimes correct — the gate asks, it does not refuse. Put a command in
permissions.ask when the action is irreversible outside the repository: publishing, tagging,
deploying, applying infrastructure.