The previous article argued that offline-first is a synchronization problem, not a local-database feature. That same distinction matters for AI-assisted development.
An agent can modify Flutter models, generate a migration, update backend code, inspect runtime state, and validate the result. Should it also be able to mutate production data?
The useful answer is not simply yes or no.
Agents should generate, explain, validate, and test migrations. They should almost never be the final authority that applies them to production.
The boundary between proposing a change and performing an irreversible production action is becoming a core architectural decision for teams using coding agents.
Serverpod 4 changes who can touch the database
Serverpod 4 puts a Flutter application, Serverpod backend, generated clients, local PostgreSQL, agent skills, and MCP tooling into one development loop.
Change model
↓
Generate migration
↓
Apply it locally
↓
Reload backend and app
↓
Inspect the result
That is excellent for developer productivity. It gives an agent a way to test the consequences of a schema change instead of guessing from source files.
It should also make teams ask a different question:
Should the same actor that writes a migration hold the credentials to execute it against irreversible data?
Code is reversible. Data often is not.
Deleting a Dart file can be reverted with Git. Deleting customer records, overwriting a history table, or running an incorrect backfill may not be recoverable in the same way.
That difference is why mature delivery workflows already distinguish code review from data operations:
Code
Developer → Git → review → CI → deployment
Database
Migration → backup → approval → execution → verification
Agents should enter this process as capable contributors, not as a replacement for the control points.
Migration generation is an ideal agent task
Schema changes are highly structured. If a model changes from fullName to displayName, a good migration candidate should preserve existing data, update generated code, find dependent references, and verify constraints.
Serverpod’s migration tooling already formalizes this work. serverpod create-migration compares the current required schema with the last migration and generates the steps to move forward. It stops when it detects a risk of data loss unless the caller explicitly forces generation.
This is precisely the kind of mechanical, reviewable work agents can accelerate:
- propose migration files and model changes;
- explain the schema diff in plain language;
- identify a destructive operation;
- generate a backfill or compatibility plan;
- run migrations against a disposable local database;
- execute tests and report evidence;
- prepare rollback or repair guidance.
The agent becomes much more valuable than a SQL autocomplete tool because it can connect the migration to models, code paths, tests, and runtime behavior.
A valid migration can still be the wrong decision
Now consider this request:
ALTER TABLE customer
DROP COLUMN customer_name;
The SQL can be syntactically correct. It can even work in a local environment.
The question is whether the column is still read by an older mobile app, a reporting service, a BI dashboard, a scheduled job, a data export, an integration, or a rollback version of the backend.
An agent working in one repository normally cannot infer every organizational dependency. Its ability to write SQL is much stronger than its ability to discover invisible consumers.
Production database risk is therefore not only a syntax problem. It is a dependency-graph and product-compatibility problem.
Database permissions should not be binary
“Database access” is too broad to be a useful permission.
| Capability | Recommended default |
|---|---|
| Read schema metadata | Allowed |
| Read anonymized fixtures | Allowed |
| Generate a migration | Allowed |
| Validate migration files and tests | Allowed |
| Apply migration to disposable local data | Allowed |
| Apply migration to shared staging | Approval required |
| Read production rows | Normally denied or tightly scoped |
| Apply production migration | Controlled CI with approval |
| Delete production tables or rows | Never autonomous |
The important question is not “should AI access the database?” It is “which environment, which identity, which action, and which review boundary?”
Make local environments intentionally disposable
The embedded local PostgreSQL workflow in Serverpod 4 is useful because it lowers the cost of learning from failure. An agent should be able to create a bad migration, apply it to test data, recreate the database, and try a safer approach.
Local: agent can experiment and reset.
Staging: CI validates; a human approves.
Production: controlled identities execute approved changes.
These environments should not have equivalent permissions. Local autonomy is a feature. Production restraint is a requirement.
Expand and contract still matters
Destructive schema changes are rarely safe as a single production step. A more compatible pattern is expand and contract:
1. Expand: add a new compatible structure.
2. Support both: write and read old plus new forms.
3. Switch: move traffic after clients are compatible.
4. Contract: remove the legacy structure later.
An agent can generate each phase, including the compatibility code and the eventual removal migration. It should not decide on its own that all phases can collapse into a single DROP COLUMN.
MCP makes a good permission model essential
MCP can make logs, source code, migration commands, and database tools easier for an agent to use. That convenience also removes friction that previously protected production systems from accidental access.
MCP’s authorization guidance recommends least-privilege scopes rather than catch-all permissions. The OWASP AI Agent Security Cheat Sheet similarly recommends explicit approval for high-impact actions, tool allowlists, audit trails, and separating decision-making from irreversible execution.
Raw execute_sql() access is difficult to govern safely. A better architecture exposes purpose-built, policy-aware tools:
Agent
↓
Governed migration tools
├── generate plan
├── run on disposable database
├── report destructive operations
└── request promotion
↓
Controlled CI identity
↓
Production database
The extra layer is intentional. It gives a team identity, authorization, redaction, approval, logging, and a chance to inspect an action before it becomes a production incident.
Review must evolve beyond SQL syntax
A migration review should answer architectural questions, not only ask whether SQL parses:
- Does this preserve compatibility with currently released clients?
- Does it need a backfill, and can that backfill resume safely?
- What is the rollback or repair plan?
- Which services, exports, and integrations consume this data?
- Does the change affect authorization or data visibility?
- Are indexes, locks, and expected downtime understood?
- Is the migration being run through the intended environment and identity?
The agent can prepare much of this review. A human still needs to make the business and operational judgment.
The healthiest workflow is supervised autonomy
Human defines compatibility and data requirements
↓
Agent updates models and proposes migration
↓
Agent validates locally with disposable data
↓
CI checks migration and application tests
↓
Human reviews data impact and approves promotion
↓
Controlled pipeline executes in production
The agent performs most of the mechanical work. The irreversible decision remains accountable to a person and an audited deployment process.
This is not a lack of trust in agents. It is sound system design. Production architecture already assumes that humans, scripts, credentials, and deployments can fail. Agents should be designed into the same safeguards.
The goal is not to grant AI more permissions. It is to give AI enough authority to automate engineering while preserving human control over irreversible business decisions.
