LSP
LSP copied to clipboard
Provide `Transport` as parameter when invoking `plugin.on_post_start`
Is your feature request related to a problem? Please describe.
When launching the LSP server for AWS Q Developer, this LSP server expects an AES encryption key to be written on stdin
- before any other messages - in order to encrypt AWS credentials that would later be sent by the LSP client. This ensures plaintext AWS credentials are not persisted in logs by LSP clients. One can observe the need to receive an AES encryption key before any other messages by reading the following code in the LSP server for AWS Q Developer:
- https://github.com/aws/language-servers/blob/main/app/aws-lsp-codewhisperer-binary/src/iam-standalone.ts
- https://github.com/aws/language-server-runtimes/blob/7e44d7516d55797cf1f7e5614dfa9fce2236e7f3/runtimes/runtimes/standalone.ts#L90C13-L90C34
Describe the solution you'd like
Within an LSP
plugin, the only opportunity for the plugin to access the process for the underlying Transport
of an LSP server - before any messages are sent to it - is within the on_post_start
hook for an AbstractPlugin
:
- https://github.com/sublimelsp/LSP/blob/fc5a7c75c8cec2e6765e218f7df980315c5c9ff3/plugin/core/windows.py#L282
- https://github.com/sublimelsp/LSP/blob/cd7cb682e634657c63105b906bacda99611846fd/plugin/core/sessions.py#L943
However, in order for the AbstractPlugin
to access the underlying process in on_post_start
, it needs to receive the Transport
instance created for the Session
. Since the initialize_async
method on Session
will send the initialize
message to the LSP server, there is no other opportunity for the LSP plugin to provide an AES key to the LSP server before other messages are sent:
- https://github.com/sublimelsp/LSP/blob/fc5a7c75c8cec2e6765e218f7df980315c5c9ff3/plugin/core/windows.py#L284
- https://github.com/sublimelsp/LSP/blob/cd7cb682e634657c63105b906bacda99611846fd/plugin/core/sessions.py#L1510
Given these constraints, it seems the best way to support the LSP server for AWS Q Developer is to provide the Transport
instance that the plugin will use as an additional (keyword?) parameter to the on_post_start
hook.
Describe alternatives you've considered
In order to get around this issue, I found that transports.py
stores a singleton Weakset
of processes launched by each Transport
instance in a variable called _subprocesses
: https://github.com/sublimelsp/LSP/blob/cd7cb682e634657c63105b906bacda99611846fd/plugin/core/transports.py#L285
Currently, I am importing this _subprocesses
from transports.py
and finding the "most recent" subprocess that the LSP plugin has not seen before. However, this is very brittle and relies on internal implementation details. It would be better for the on_post_start
hook to explicitly provide the Transport
instance, so there's no possible ambiguity in resolving the correct process to write the AWS encryption key to.
Additional context
I am authoring an LSP plugin for AWS Q Developer at this time, and Amazon will be unwilling to compromise the security profile of this LSP plugin by sending unencrypted AWS credentials over LSP messages to the LSP server for AWS Q Developer. I kindly ask that we consider this concern critical to the success of new LSP plugins that will be meaningful to Sublime Text users.
I would be happy to author a PR for this issue as well, but I'd like to get alignment with the community first before doing so, in order to address any material concerns they may have.