Generating a vigenere square in LaTeX3
About your points:


The interface seems pretty clear.
If you fear about the \arraystretch parameter being abused, you're right: on a double spaced document all tables come out horribly and local remedies are often necessary. Maybe adding a stretch key could help for these cases.
Yes, you're abusing local and global assignments.


Some comments about the code: 


There is no point in the key alphabet to set a tl variable, which is then converted to a clist
There's no need to set a .default:n for the font key: the value specified with .default:n would be used if the key is called without assigning a value
\int_step_inline:nnnn can be done more simply using the * feature of tabular
Never use \expandafter in expl3 code
You should not use global assignments on local variables
\clist_gpop:NN should be \clist_gpop_left:NN (but I changed it into \seq_pop_left:NN)
One can do with a simpler loop, using \prg_replicate:nn


I'd also prefer to prepare the table body outside the table, with sequences instead of clists, which are less efficient.



\documentclass{article}
\usepackage[landscape]{geometry}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand { \printvigeneretabular } { O{} }
 {
  \vigenere_tabular:n { #1 }
 }

% keys
\keys_define:nn { vigenere }
 {
  font      .code:n       = { \cs_set_eq:NN \__vigenere_font: #1 },
  font      .initial:n    = { \small },
  tabcolsep .dim_set:N    = \l__vigenere_tabcolsep_dim,
  tabcolsep .initial:n    = { 3pt },
  alphabet  .clist_set:N  = \l__vigenere_alphabet_clist,
  alphabet  .initial:n    = { A, B, C, D, E, F, G, H, I, J, K, L, M,
                              N, O, P, Q, R, S, T, U, V, W, X, Y, Z }
 }

% variables
\tl_new:N \l__vigenere_tablebody_tl
\seq_new:N \l__vigenere_alphabet_seq

% internal function
\cs_new_protected:Nn \vigenere_tabular:n
 {
  \group_begin:
  % set the keys
  \keys_set:nn { vigenere } { #1 }
  % make a sequence from the alphabet
  \seq_set_from_clist:NN \l__vigenere_alphabet_seq \l__vigenere_alphabet_clist
  % set the font and the tabcolsep
  \__vigenere_font:
  \dim_set_eq:NN \tabcolsep \l__vigenere_tabcolsep_dim
  % prepare the table body
  \tl_clear:N \l__vigenere_tablebody_tl
  \prg_replicate:nn { \seq_count:N \l__vigenere_alphabet_seq }
   {
    \tl_put_right:Nx \l__vigenere_tablebody_tl
     {
      \seq_use:Nn \l__vigenere_alphabet_seq { &amp; }
      \exp_not:n { \\ \hline }
     }
    \seq_pop_left:NN \l__vigenere_alphabet_seq \l_tmpa_tl
    \seq_put_right:NV \l__vigenere_alphabet_seq \l_tmpa_tl
   }
  % make the table
  \tabular { | *{\clist_count:N \l__vigenere_alphabet_clist }{ c| } }
  \hline
  \tl_use:N \l__vigenere_tablebody_tl
  \endtabular
  \group_end:
 }
\ExplSyntaxOff

\begin{document}

\printvigeneretabular

\printvigeneretabular[font=\tiny,alphabet={1,2,3,4,5,6,7,8,9,10},tabcolsep=1pt]

\end{document}