Setting up the Snyk Language Server in Emacs
At DroneDeploy, we've been experimenting with more and more AI tools like GitHub Copilot, but we're concerned about the security implications of incorporating complex generated code snippets into our production projects. To help out, we're experimenting with the Snyk language server, which provides security insights and vulnerability scanning for code and dependencies. However, there's no official package for using the Snyk language server in Emacs. So, I dove into making Snyk and Emacs get along nicely, a feat which returns exactly zero search results as of the writing of this post. I finally got it working, and I hope this helps anyone else looking for a solution to the same issue.
Update
Since the writing of this post, we've concluded our experiment and found that Snyk was not worth the cost for us, and we find more value in investing in better peer review practices instead. However, the process of setting up a language server configuration was still interesting.
Before we start, you should already:
- Be somewhat familiar with Emacs Lisp since these steps don't explain a whole lot and you should always be wary of copying code off the Internet.
- Be using LSP Mode—as of right now, the built-in Eglot (in v29+) can't run add-on servers in parallel, so LSP Mode is the only option.
Snyk Language Server Setup
Since no one seems to have written about this before, this may not be a perfect approach, but this is the workflow I've found to be effective. The official IDE integration documentation is a bit outdated, so the following steps reference the current server documentation.
- First, install the server using the bash installer script provided by Snyk: snyk/snyk-ls/main/getLanguageServer.sh. This is basically a fancy wrapper around a curl call, but don't blindly run scripts from the Internet. Please do take a look at what this script is doing before you run it on your own system.
-
Install the Snyk CLI (
brew tap snyk/tap && brew install snyk). This step lets you get your authentication token. Since the Snyk language server supports automatic authentication, this shouldn't actually be necessary, but I had issues with excessively repeated re-authentication, so the token provides a workaround. -
Run
snyk config get apito actually get your token after authenticating in your browser. Especially if your config is version-controlled, do not commit the token; load it from an external source (myinit.elloads a git-ignoredinit.local.elif it exists, that's one place to put such a token). - Finally, register the LSP client with LSP Mode:
(lsp-register-client
(make-lsp-client
:server-id 'snyk-ls
;; The "-o" option specifies the issue format, I prefer markdown over HTML
:new-connection (lsp-stdio-connection '("snyk-ls" "-o" "md"))
;; Change this to the modes you want this in; you may want to include the
;; treesitter versions if you're using them
:major-modes '(python-mode typescript-mode)
;; Allow running in parallel with other servers. This is why Eglot isn't an
;; option right now
:add-on? t
:initialization-options
`(:integrationName "Emacs"
:integrationVersion ,emacs-version
;; GET THIS FROM SOMEWHERE ELSE, don't hardcode it
:token ,snyk-ls-token
;; Enable these features only if available for your organization.
;; Note: these are strings, not booleans; that's what the server
;; expects for whatever reason
:activateSnykCodeSecurity "true"
:activateSnykCodeQuality "true"
;; List trusted folders here to avoid repeated permission requests
:trustedFolders [])))
Using Snyk in Emacs
After setting everything up, simply open a file using one of the major modes you configured above. If it's not in one of the :trustedFolders, Snyk will ask you if you'd like to trust the one you're in. Keep in mind that Snyk takes a few seconds to start once you open the first file in a project. So, if you don't see it right away, just be patient.
And there you have it! You can now use the Snyk language server in Emacs.
Check out my full Emacs configuration if you'd like to see how else I bend Emacs to my will.