Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make copilot not leak secret credentials with Neovim plugin?

If you install the copilot neovim plugin following the official instructions, it is always on, also when you type -say- pass edit www.mybank.com/credentials which decrypts your GPG encrypted file and put it in /dev/shm for editing - oh, and copilot now sends its contents over the network to an A.I. that you told it was OK to use your stuff for training.

So, apart from deleting the copilot plugin and never using it again; is there a way to make sure this never happens again?

PS This is related: Can you make GitHub Copilot opt-in on a per-project basis? but that talks about VS, not neovim.

like image 516
Carlo Wood Avatar asked Sep 30 '25 10:09

Carlo Wood


1 Answers

The way I solved this is by moving ~/.config/nvim/pack/github/start/copilot.vim to ~/.config/nvim/pack/github/opt/copilot.vim - to stop it from loading at all under normal circumstances.

Then I added the following to the bottom of my ~/.config/nvim/init.vim:

" Only load Copilot if COPILOT_EXTENSIONS is set and contains the file extension used.
function! ShouldLoadCopilot()
  " Check if environment variable exists
  if empty($COPILOT_EXTENSIONS)
    return 0
  endif
  
  " Convert space-separated list of extensions into dictionary.
  let allowed_extensions = {}
  for ext in split($COPILOT_EXTENSIONS)
      let allowed_extensions[ext] = 1
  endfor
  
  " Check current file extension.
  let ext = expand('%:e')
  return get(allowed_extensions, ext, 0)
endfunction

command! LoadCopilot call LoadCopilotIfAllowed()

let g:copilot_loaded = 0

" Add Copilot status to statusline.
function! CopilotStatus()
  return get(b:, 'copilot_enabled', 0) ? ' Copilot:ON' : ''
endfunction

" Construct statusline.
set statusline=%<%f\ %h%m%r
set statusline+=%=%{CopilotStatus()}\ \ 
set statusline+=%-14.(%l,%c%V%)\ %P

function! LoadCopilotIfAllowed()
  if !g:copilot_loaded
    if ShouldLoadCopilot()
      packadd copilot.vim
      Copilot auth
      let g:copilot_loaded = 1
    else
      echo "Copilot not loaded."
      return
    endif
  endif

  if ShouldLoadCopilot()
    Copilot enable
    let b:copilot_enabled = 1
  else
    Copilot disable
    let b:copilot_enabled = 0
  endif
endfunction

" Auto-check loading of Copilot on file open.
autocmd BufRead,BufNewFile * LoadCopilot

Now it is required to have an environment variable being set, namely (say)

export COPILOT_EXTENSIONS="c h cpp hpp cxx hxx"

with space separated file extensions, before the copilot plugin is even loaded. Also upon switching between files within a session, the plugin is disabled if the extension doesn't match (though the plugin isn't unloaded).

I have great control over my environment by using cdeh, which means that environment variables are set and unset as a function of the current directory that I'm in. For example, I added export COPILOT_EXTENSIONS="c h cpp hpp cxx hxx" to /home/carlo/projects/env.source so that it is set, and only set, while I'm working on any of my C++ projects.

like image 183
Carlo Wood Avatar answered Oct 02 '25 04:10

Carlo Wood



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!