Setting up the Snyk Language Server in Emacs

Keeping code secure is more important than ever, especially as tools like GitHub Copilot make it easy to incorporate complex code snippets without fully understanding their implications. These tools have a minor but real tendency to introduce security vulnerabilities that can be difficult to catch when you're not writing the code yourself. That's where tools like Snyk come in, helping to find and fix these vulnerabilities in both your code and dependencies.

However, there's no official package for using the Snyk language server in Emacs. So, driven by the need to ensure the security of code generated by Copilot at my job, 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.

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.

  1. 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.
  2. 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.
  3. Run snyk config get api to 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 (my init.el loads a git-ignored init.local.el if it exists, that's one place to put such a token).
  4. 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 to keep your code secure and free of vulnerabilities as you write bugs.