Last Updated: 10/01/2026
Production Rails console access is restricted. Teams that need a command run in production start by submitting a ticket to #vfs-platform-support using the /support command. Platform Support responds with the Vets-API Prod ArgoCD Command Run Request template, which the requester completes, and then attends the session together with Platform Support.
This page defines what Platform Support will run, what it will not run, and where the "will not" requests should go instead.
Audience: Product teams submitting requests, and the Platform Support (Tier 1) and Backend (Tier 2) engineers who service them.
Why access is limited
Access to production systems is controlled through group policies. Consistent with the NIST Risk Management Framework, access is granted on the principle of least privilege: users are provisioned only the functions and permissions necessary to perform their authorized duties, and access to specific systems and functions must be explicitly justified by the requester's role and the task at hand.
Production Rails console access is treated as break-glass level access. It is not part of baseline engineering permissions.
That principle is why the bar below exists. A request that cannot be tied to the requester's role and a specific task does not meet it.
Hard requirements for every session
Two people, one of them the requester. All console sessions require a minimum of two people present on a private VA Microsoft Teams meeting for the duration of the session, and one of the two participants must be the author of the code or commands being run.
Never run commands alone. Sessions must not proceed if only one qualified person is available.
Attribution. Console sessions are audited by console1984. When prompted, the person running the console fills out their email and the purpose for the session. Put the request ticket number in that prompt, so the session can be traced back to this request.
What Platform Support will run
A request is in scope when all of the following are true:
-
Read-only. The command does not write to the database, the pod filesystem, S3 or other object storage, email or other notifications, or any external API beyond a pure GET. It does not enqueue Sidekiq jobs or change Flipper flags.
-
Reasonably sized. Under 100 lines. See the guidance below.
-
Pre-prod tested. The same script has been run successfully in staging, and the request links to that run.
-
Efficient. It meets the performance expectations below.
-
Justified. The request names a product and team, links the ticket or incident driving it, and ties the need to the requester's role and task.
-
Approved. A Backend lead or product owner from the requesting product line is tagged on the request.
-
Attended. The author of the script is available to join the session.
-
Ticketed. A
/supportrequest exists in #vfs-platform-support and is linked.
Typical in-scope requests:
-
A simple
countorexists?check against a table to confirm whether a record was created. -
Reading a Flipper flag's current state.
-
A small read-only lookup by a non-identifying key (a job ID, a form ID, a
created_atwindow). -
A bounded lookup that returns PII/PHI, handled per the rules below.
Handling PII/PHI
We can run commands that return PII/PHI. What matters is how the data is handled during and after the session.
-
If we send results, it is by encrypted VA email. From a VA address to another VA address. Never over Slack or unencrypted email. Results can also be written to an approved destination for the requester to collect, see Where results can be written.
-
Never run the session alone. Two people, one of them the script's author.
-
Meet on a private VA Microsoft Teams meeting.
-
Do not paste identifiers into the request. Reference a ticket or use a variable rather than putting SSNs, ICNs, file numbers or names in the issue body.
-
Return only what is needed. If the output can be masked or narrowed and still answer the question, mask or narrow it.
-
All applicable VA policies for the handling of Personally Identifiable Information (PII) and Protected Health Information (PHI) apply for the duration of the session. Do not expose, copy, or transmit sensitive data outside of authorized boundaries.
Where results can be written
Some result sets are too large to return through the session. A command may write its own output to an approved destination, and the requester either collects it there or receives it by encrypted VA email.
-
Approved destinations: AWS GovCloud S3 (
us-gov-west-1) and VA SharePoint. -
Name the destination in the request before the session, including the bucket or folder.
-
Either the requester collects it, or we send it. If the requester already has access to the destination, they collect it there and the request should say so. If they do not, the file goes to them by encrypted VA email, from a VA address to a VA address. Say which of the two applies in the request, so nobody is left waiting on a file that was never going to be sent.
-
Clean up afterwards. Once the requester has the file, delete the copy left in the destination. Say in the request who will delete it and when. Results containing PII/PHI should not sit in a bucket indefinitely.
-
This covers output only. A command that writes anything else, to any other destination, is still out of scope and belongs in a rake task.
Not approved: personal or team cloud storage, local machines, any non-VA service, or any destination not named in the request.
Any incidental exposure of PII/PHI during a session must be handled according to VA data-handling and incident-response requirements. See Reporting an accidental disclosure.
If anything about a request feels off, raise it with Jennifer Kramer before running it.
What Platform Support will not run
Anything that writes
A command that creates, updates, deletes, or destroys records, or writes to the filesystem, S3, email, an external API, Sidekiq, or Flipper, is a production data change. Production data changes belong in code review, not in a console session.
Where it goes instead: a PR-reviewed rake task or migration in vets-api, reviewed and merged through the normal process, then run.
Anything not tested in staging
"Has this been tested on staging?" answered "Yes" is not evidence. The request must link the staging run: a Slack permalink, a screenshot, or a ticket.
If a script genuinely cannot be exercised in staging, say so in the request and explain why. That is a conversation, not an automatic decline, but it raises the bar on everything else.
Where it goes instead: back to the requester, to run in staging first.
Anything without a business owner
A request needs a named product, a linked ticket, and a tagged approver from the requesting product line.
Where it goes instead: back to the requester, to get product-line approval.
Anything that puts production performance at risk
See the performance expectations below. A query that would scan large portions of production tables is out of scope on that basis alone, independent of everything else on this page.
Script size and structure
Keep it under 100 lines. This is guidance rather than a hard gate, but a script over 100 lines will likely be pushed back to become a pull request.
Alongside length:
-
Keep the code readable and concise. The person running it has to understand it well enough to spot something going wrong mid-session.
-
Prefer narrow, bounded queries over anything open-ended.
-
If it defines several methods or classes, that is a signal it belongs in a pull request regardless of line count.
Performance expectations
Console sessions can degrade the Veteran experience and platform stability if they are not efficient. Before a session:
-
Authors must have tested scripts in lower environments.
-
The script must not make excessive calls to back-end services.
-
Queries should:
-
Filter on selective, indexed columns so the query touches as few rows as possible.
-
Select only the columns you need, and avoid pulling large text fields unless the question requires them.
-
Bound the result set with a limit or a narrow time window rather than scanning a table.
-
-
As a general rule, if a database step takes longer than 30 seconds to complete, consider ways to improve efficiency.
-
If there are concerns about system impact, consider running the job off hours or incrementally.
For questions about performance, contact #platform-cop-backend.
If your request is declined
A decline is a routing decision, not a judgment about the request's merit. The engineer closing it should name which rule above applies and where the request goes instead. If that is unclear, or you think the rule is wrong for your case, raise it in #vfs-platform-support.
Reporting an accidental disclosure
If Veteran identifiers have been pasted into a request, or PII/PHI is incidentally exposed during a session, close the request and notify #vfs-platform-support immediately, and follow VA incident-response requirements. Do not wait to see whether anyone noticed.
Help and feedback
-
Get help from the Platform Support Team in Slack.
-
Submit a feature idea to the Platform.