Skip to content

Protecting data

Everything a tool returns becomes part of your conversation with the LLM. It’s sent to your LLM provider, and it may be kept in your IDE’s chat history. This page shows what each tool returns, and how to keep personal data and secrets out of the conversation.

  • Definitions, from search_definitions, describe_record, describe_component, describe_app_engine, and find_references: names, descriptions, and structure. The only personal data is the user ID of whoever last changed each definition, in lastUpdatedBy. find_references names public queries, but only counts private ones.
  • Code, from get_peoplecode, get_sql, and search_code: PeopleCode and SQL as they’re stored. Code holds personal data or secrets only if someone wrote them into it; see Secrets in code.
  • Translate values, from get_translate_values: codes and their names.
  • Security, from get_security: permission lists and roles, with how many users have each role. Users are counted, never named.
  • Data, from run_select: rows from the tables your administrator allows. That’s everything those tables hold, except masked columns.
  • To your LLM provider, as part of the conversation, unless you host the model yourself. Check that your organization’s agreement with the provider covers this data, in particular how long the provider keeps it, where it’s processed, and whether it may be used to train models.
  • Into your IDE’s chat history, which, depending on the IDE, may be saved on your machine or in the IDE vendor’s service.
  • Not into the audit log. The audit log records each call’s arguments and how many rows came back, never the results.
  • Not into the server’s storage. The server keeps definitions in a short-lived memory cache, never caches run_select results, and writes nothing to disk except the audit log.

run_select is the only tool that reads application data, so it has the most controls:

  1. It’s off by default. Turn it on only if developers need to see data, and think twice in a database that holds real personal data.
  2. Allow only the tables that are needed. The allow-list starts empty, and the database account needs its own grant for each table you add, so a table is readable only when both allow it.
  3. Mask sensitive columns. Values in the columns listed in sensitive_columns come back as ***, and those columns can’t be used in conditions or expressions, where masking couldn’t be guaranteed.
  4. Prefer views. For the strongest protection, allow a view that leaves sensitive columns out, and grant the account access to the view instead of the table.
  5. Require a separate permission. On a shared server, every tool needs the metadata scope in the person’s access token, and run_select also needs the data scope. Your identity provider decides who can get it.
config.yaml (shared server, excerpt)
auth:
issuer: https://login.example.com/
audience: api://aipeoplesoft-mcp
scopes:
metadata: aips.metadata.read # needed for every tool
data: aips.data.read # also needed for run_select

A run_select call from someone whose token lacks the data scope is refused with HTTP 403 and an insufficient_scope error that names the scope, as the MCP authorization specification describes. The IDE can then ask the person to sign in again for the extra scope, which the identity provider grants only if they’re allowed it.

Development and test databases are often copies of production, with real personal data in them. AI Assist reads whichever database it’s pointed at, so treat a copy like production: mask or scramble personal data when the copy is made, or keep run_select off in that database.

PeopleCode and SQL sometimes hold things that shouldn’t be there, such as passwords, API keys, or real employee data used for testing. The code tools return code as it’s stored. The server doesn’t try to find and hide secrets, because no pattern can find them reliably.

Before you connect AI Assist, have your database administrator search for them directly in the database, as in Find planted instructions, with terms such as PASSWORD, SECRET, and TOKEN. Run that search without AI Assist, so any secrets it finds aren’t sent to the LLM. Move the secrets you find out of the code, and change them, since everyone who could read the code could read them too.

The audit log shows what people looked at, including the SQL of every run_select call and the text of every search. Restrict who can read it, and keep it only as long as your policies require. See Audit log.