GitHub/BitbucketからAccess Tokenを使ってdeployする

あるいはサーバ上で private package を bundle(npm) install したい。

課題

今回の課題はこれ。

private な repos をサーバ上で clone したい

もう少し詳しく書くと直接の git clone もそうだし、bundle install や npm install で private repos から package を install したいが、もちろん

秘密情報は repos に入れたくない

というものである。

※ Access Tokenが使えれば他のサービスでもサーバでもよい。

解決方法

  1. 環境変数と.netrcを使う
  2. 環境変数と動的なURL書き換えを使う

1. 環境変数と.netrcを使う

この方法を知ったきっかけはこれ。

timshadel/heroku-buildpack-github-netrc: Heroku buildpack to access private Github repos over HTTPS without storing user/pass in your files.

やってることは、

  • 環境変数にトークンを保存
  • build 時に環境変数から ~/.netrc に保存し、git の機能で ~/.netrc の情報で認証を通す

これで確かにリポジトリに認証情報を残さずに private repos から clone できる。

もちろん token の権限設定は必要最小限にしておこう。

サーバ上の環境変数設定を簡単に行える環境ならこれが楽だと思う。

2. 環境変数と動的なURL書き換えを使う

Capistrano で clone することで deploy する際には上とは異なる方法を利用することにした。

Easier builds and deployments using Git over HTTPS and OAuth

の情報をもとに Capistrano を叩く環境に変数でトークンを保存したうえで URL を

set :repository, "https://#{fetch(:github_auth_token)}:x-oauth-basic@github.com/{user}/{repos}"

と、cap を叩く時に書き換える。Gemfile や package.json がないならこの方法も使える。

※ Gemfile や package.json がある場合は頑張って上の buildpack と同じようなことをしてあげることになると思う。

手元の環境からも deploy したい場合は dotenv のようなものを使うか、.netrc に情報を保存するのもアリ。Capistrano 側のコードはこんな感じになる。

set :github_auth_token, ENV['GITHUB_AUTH_TOKEN'] || Netrc.read['github.com']['login']

..netrc を読み書きできる便利 gem はこれ。

heroku/netrc: Reads and writes netrc files.

なぜ他の方法ではないのか?

ここから先はちなみに情報。

Git 自体が対応している認証情報の保存方法がいくつかある。最近では自分で手で作業する場合はこのうちのいずれかを利用しているケースが多いと思う。

Git - 認証情報の保存

によると

  • cache (15分だけメモリに保存)
  • store (永続的にファイルに保存)
  • osxkeychain (macのkeychainアプリにパスワードを保存)
  • wincred (Windowsのkeychainのようなもの)

の4つに対応している。

ただしこれらは、人間がパスワードを入力しその認証情報を保存する、という流れを想定しており、Coutinuous Deployment で利用するにはイマイチである。

Git でパスワードを入力せずに push / pull するということでロートルがすぐに思いつくのはパスフレーズなし鍵認証の ssh を使う方法である1が、今回行おうとしているのは

サーバ上で git clone や bundle install や npm install したい

ということであり、サーバ上に余計なものは入れたくないし、まして Heroku などの PaaS 上では採用できない方法である。(deploy用の公開鍵を保存する機能はあっても秘密鍵を保存する機能が存在しなかったりする。)

なぜ.netrcで可能なのか?

最後になるけど、なんか普通に .netrc って言ってるけど、そもそもこれ何?って話。

  • git は http での転送の際に cURL を利用している
  • cURL は .netrc に対応している

..netrc って古の ftp ですよね?ってぼくは思っていたのですが、cURL 力不足ということのようでした。(実は cURL あまり好きじゃなかった)

cf.

Man page of NETRC

  1. なぜなら Git で http での push / pull が使いものになるのは 1.6.6 で登場した Smart HTTP が使えるようになる 2009年以降の話であり、それまでは CVS や Subversion でもおなじみだった ssh と組み合わせる方法の方がポピュラーだったのだ。 

More

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Dev Jekyll