Let's assume this is not a tiny chroot or container with only what they need, but rather a general purpose multi user operating system.
With sufficient automation, logging into the host may not be required. Perhaps provide via some self-serve system these limited options, which the automation does.
For letting them do the thing on the host, try what I would call a captive text menu. Which is a script you may need to write.
Strictly confining the person from doing other things requires several tricks.
- Login as a non-privilaged, ideally unique to them user. Escalate for privilaged stuff with tools like doas or sudo.
- Mandate this menu is what runs with OpenSSH
ForceCommand
blocks.
- Also exec it from shell profiles. exec so it replaces the shell process, and when the menu exits so does their session.
- Trap signals in the menu script.
- Beware programs that can run arbitrary commands. Shelling out is trivial in vim, the command is
:shell
- Write and use as menu items wrapper scripts, for more complex operations or more control over output.
Take your pick of scripting languages to write the menu in. Consider using an existing text menu library. An input loop by itself is not difficult, but making it robust, easy to modify, and with good UX is what you actually want in production.