Got Some \W+ech?

Could be Japanese. Could be English. Android, セキュリティ, 機械学習などをメインに、たまにポエムったり雑感記載したりします。

セキュリティエンジニア in スタートアップが大事にすべき3つのポイント

FOLIOアドベントカレンダー ラストの個人投稿3回目です。過去2回は当社で利用しているプロダクトについてお話しましたが、今回は本ブログでも初のポエムになります。

adventar.org

セキュリティエンジニア(以降、エンジニア)がユーザー企業のスタートアップに転職したケースを目にする頻度が増え、時代の節目のようなものを感じます。

もちろん、昔からそういったスタートアップに参加するエンジニアはいたと思いますが、パブリックな情報として流れることは少なく、ましてや、経験した本人による体験談・ポエムは目にした記憶は全くありません。

そこで、今回はキャリアの選択肢の1つであろうスタートアップへの就職についての理解を深めるため、私の 超個人的経験と見解 をもとに、スタートアップで働く際に大事にすべきポイントをお話します。

どういうポジションから語るか

主観的な意見を述べるということは一定のポジションを取ることになりますので、最低限のバックグラウンドを共有させていただきます。

来歴

  • 2011年: 某Nなセキュア。MSS/CSIRT/SOCに従事
  • 2014年: 某MでFなFintech企業。創業2年目に参加して上場まで、社員数 50 -> 300を経験。モバイルアプリ開発とセキュリティ(なんでも)に従事
  • 2018年: FOLIO。創業2年目。セキュリティ(なんでも)に従事 <- 今ここ★

スキルセット

  • Blue成分多め。Red成分はGPENとWeb診断をツール回してできるくらい。
  • 今後攻めていきたい分野
    • AWS/GCP
    • CNCF系
    • OIDC/FIDO/Open Banking/Decentralized Identity/Self-sovereign Identityのような本人確認・認証・認可まわり

定義

  • スタートアップ: 創業数年で、新たなビジネスモデルを開発して市場を開拓する段階の企業(コピペ)。セキュリティ専任はいない。

このような人間が超主観的に語るので、1㍉も賛同できない方はきっといると思います。そういった方は是非、別の経験と真実を共有いただければと思います。では、本題に入ります。

本題: スタートアップに入る際に大事にすべき3つのポイント

順番に紹介していきます。

VisionとCultureへ共感する

Visionはスタートアップが目指したい世界観であり、Cultureはその構築・運営時における価値観です。 そういった参加先のVision/Cultureにある程度、共感・納得しておくことが大事だと思います。 これは、リスクの多いスタートアップはは、ある程度の覚悟とその先にある世界観へ希望を持ってことにあたる必要があるためです。

どのようなリスクがあるのでしょう?まず事業リスクです。 よく言われることですが、創業から3年後のスタートアップは約50%が失敗します。そもそも市場の開拓 = 不確実性の高い領域で勝負するのですから、勝負に負けた場合、転職1年目で会社が潰れてしまうことだってありえます*1

f:id:kengoscal:20181225175336p:plain
Years in existence

*2

事業リスクのような外部だけでなく、社内部にもリスクはあります。 大きなリリースに向けた長時間勤務のような話がまずあげられます。ですが、これはスタートアップでなくともある話です。成長過程のスタートアップしかないリスクだと、いわゆる成長痛による社内の雰囲気の悪化などがあります。例えば、人事評価や組織の階層化の構築・運用開始時におけるメンバー間のスタンスの違いや、あるいは現在進行系の案件とVisionへのギャップを感じたコアメンバーの離脱などが挙げられます。

セキュリティエンジニアにとっては(プレイヤーとしての)成長の機会損失リスクです。確かにスタートアップは身軽ですが、身軽さ故に良くも悪くもおざなりになってる施策があります。そのボール拾いが最初の1年間のお仕事になる覚悟は必要です。例えば...

  • 使い回されたパスワードの撲滅
  • ばらまかれた特権の整理
  • 整備されていないワークフローの洗い出し
  • 業務端末一覧化
  • 私用端末の撲滅

これらは最高に泥臭いですが、拾わなければいけないボールです。技術的なチャレンジはないただ淡々とこなす作業です。もちろん創意工夫の余地があることは否定しませんが、そんな余裕は普通ありません。技術にチャレンジする機会がすくないため、1人のエンジニアとしての技術的な成長をあきらめる一定期間というのは確実にありあmす*3

このように、スタートアップには様々なリスクがあります。そのような環境で働くことに本当にそれだけの価値があるのでしょうか? それを見出すのがVisionとCultureです。なにも100%共感すべき、ビジョナリーカンパニーのように信望しろ、と言いたいわけではありません。 きたるツラミと戦うには一抹の希望を胸に抱かなければならなく、そのためにはVisionとCultureへの共感と納得が必要なのです。

多面的・多角的なインプットをする

スタートアップに入るセキュリティエンジニアは、おそらく最初のセキュリティエンジニアです。 そんなエンジニアにとっての最大の味方は上層部です。Visionを実現したい上層部はきたるリスクに対処する専門家の味方です。他のメンバーも同じです。

ただ、ちょっと穿った見方をすると「セキュリティなら仕方ないよね」という言い訳が通りやすい環境で、もっと穿ってみると専門家に物申す批判者が少ない環境です。

最高なUsableなセキュリティを実現しても、それが業界のレギュレーションに準拠していないならば、それは業界内の独り相撲です。逆にレギュレーションにきっちり100%沿っていても、実装がスタートアップの実態にあってないこともありえます。

https://pbs.twimg.com/media/CT7GyGQWUAAhGlm.png

技術が、規制が、コンプライアンスのうち何が優先度たかいのかという話ではありません。エンジニアがボトルネックである、という話です。1人の人間として得意とする or できることが、必ずしも全体における最適な選択肢ではない可能性があります。そして、ある選択肢を選んだエンジニアに突っ込める人はスタートアップでは本当に少ないのです。そのため、エンジニアの一面的な知識・経験ではそれ自体がリスクになる可能性があります。

したがって、エンジニアは最新技術のインプットのみならず、 フレームワーク*4やら業界規制やら社内の状況やらを様々な側面から入手・分析し、知識として蓄え、然るべき時に然るべきアウトプットを出せるようにしなければなりません。研ぐ対象が爪だけではなく、牙もわざマシンも魔具を準備しておくのです。

ビジネスとセキュリティのゴールをアライメントさせる(あるいはしているか確認する)

さて、エンジニアとして頑張った甲斐あって(?)会社も軌道にのったとしましょう。確実にその成長に貢献したと思っているところに、評価者から次のようなありがたいコメントを頂戴することもあります。

「何も成果をだしてない」

これはエンジニア本人にも評価者にも非常に悲しいことです。しかし、感傷的になっても生産的ではありません。原因を考えてみましょう。 恐らく、根本的な原因は評価者とセキュリティエンジニア間のゴールの共有不足ではないでしょうか。評価者はメンバーの貢献具合を計測します。そこには数字があり、スケジュールがあり、ロードマップがあります。セキュリティサイドにそれがない場合、またあっても共有不足で認識されていなければ、いくら貢献したと思っても評価されないのです。

せっかく使い回しのパスワード撲滅や全社2要素認証導入など泥臭い、しかし大事な作業をしたところで、その成果を認められなくては悔しくて夜も眠れないでしょう。悲しい思いをしたくないのであれば、セキュリティの戦略を作った上で、ビジネス上の戦略とのアライメントをとれるよう、密なコミュニケーションで働きかけましょう。ラフでもするのとしないのでは天地の差があります。

まとめ

スタートアップという特殊な環境にいる、特殊なセキュリティエンジニアだからこそ大事にしたい3つのポイントを共有させていただきました。この情報がスタートアップに対する転職の流動性にポジティブに働くかネガティブに働くかはわかりません。しかし、これをもとによりリアルなキャリア選択ができるようになることをのぞんでいます*5

*1:そうなった方にこの間お会いした

*2:https://www.fool.com/careers/2017/05/03/what-percentage-of-businesses-fail-in-their-first.aspx

*3:個人活動は別

*4:例: https://csrc.nist.gov/Projects/Risk-Management

*5:できれば、一緒に働きましょう

AzureADでYubiKeyを管理しつつ認証(TOTP)する #azureAD #yubikey

FOLIOアドベントカレンダー 8日目、個人投稿2回目です。

adventar.org

8日に当社の勉強会「Scramble!」に来ていただいた皆様、ありがとうございました。

folio.connpass.com

FOLIOの情報戦略のこれから_-_情報システムを添えて.pdf - Speaker Deck

その場でお話した通り、当社はMicrosoft365を中心にした社内基盤へ生まれ変わろうとしています。 Microsoft365のIdP「AzureAD」は柔軟かつ強固なMFA方式を自由に選べます。通知ベースのMFAもデフォルトでついてくるスグレモノです。*1 特に10月からPublic PreviewになったハードウェアキーによるTOTPは、自分にとって嬉しいニュースでした。なぜなら、何らかの理由でスマホを使えないメンバーに、完全に独立したセキュリティキーをお渡しできるからです。 そこで本エントリでは、それについて触れてみようと思います。

techcommunity.microsoft.com

手順としては次の通りになります。ただし、ベンダーからバルクで購入する場合、1は不要になるようです。2までやってくれるかは原文からよみとれませんでした。

  1. YubiKeyに対するシードの設定
  2. YubiKeyとユーザーのヒモ付情報のAzureADアップロード
  3. 登録されたYubiKeyの有効化

YubiKeyに対するシードの設定

Yubikey Command Manger (CLI) を使って、シードをYubikeyに設定します。

% ykman oath add ken5scal@example.com
Enter a secret key (base32): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
A credential called ksuzuki@folio-sec.com already exists on this YubiKey. Do you want to overwrite it? [y/N]: y

YubiKeyとユーザーの紐づけたCSVファイルをAzureADにアップロード

さきほどのシードを登録したYubikeyをAzureADに登録します。その際に、下記のようにそのYubikeyとユーザー(UPN)を紐付けることができます。

upn,serial number,secret key,timeinterval,manufacturer,model
ken5scal@example.com,111111,SECRET_KEY,30,YubiKey,HardwareKey

f:id:kengoscal:20181207211959p:plain
アップロード先

登録されたYubikeyを有効化

アップロードが成功したら、対象のYubiKeyを有効化します。 f:id:kengoscal:20181207212419p:plain

有効化する際に求められるOTPは、Yubikeyを挿した状態のYubikey Authenticatorに表示される値を入力すればOKです。

f:id:kengoscal:20181207213420p:plain

同様にYubikey Authenticatorで表示された値を用いて、ログイン(2段階目)をできます。

f:id:kengoscal:20181207214921p:plain

このようにして、Azure ADに対してYubikeyでOTPすることが可能です。

終わりに

実はいくつか制限があり、現在は1人に付き5デバイスまでしか設定できません。また、これは私だけかもしれませんが、一回登録を解除(削除)したYubiKeyはたとえシードを再設定したとしても、最有効化できないようです(失敗します)。Public Previewだからかもしれません。

とはいえ、やはり一番めんどくさいのはシードの設定とCSVのアップロード、そして有効化の一連の作業です。情シスの身として考えると、そこらへんの工程はできるだけなくして欲しいと思います。将来的には個人向けOffice365アカウントやGSuiteのように、そもそもYubikeyを指すだけで完結するようなることを期待しています。

9日目は @laysakuraさんです

*1:Oktaは月$6追加料金がかかります

踏み台環境でテレポートする

FOLIOアドベントカレンダー1日目です。

adventar.org

ブラウザから使える踏み台(Bastion)であるGravitational社のTeleportについて書きます。SSH秘密鍵を始めとしたクレデンシャル情報をローカルからなくす(もしくはクレデンシャルのアクセス権限を永続化させない)というのは、おそらくセキュリティに携わる人の課題の一つだと思います。 踏み台の文脈におけるその課題は、AWSではSession Manager、GCPではCloud Shellなどで実現しつつあります。Teleportもそのようなソリューションの1つと捉えることができるでしょう*1

おそらく日本語の公開事例としては初でやったぜこれでホットエントリで間違いなし承認欲求万歳、とウキウキしながらアドベントカレンダーの準備をしてたら、クラウドネイティブのすだちくんに先を越されて泣いています。あー悔しい。

blog.animereview.jp

というわけで、全体的なTeleportの紹介はそちらに譲り、本エントリでは当社ユニークな構成についてお話させていただきます。

  1. 当社の構成
  2. 改善ポイント
  3. 当社の貢献

当社の構成

構成そのものはスタンダードです。TeleportプロキシはCLIとブラウザで受けるために、それぞれNLBとALBを用意しています。 エンタープライズライセンスは共通するS3バケットにいれています。

f:id:kengoscal:20181130142422p:plain

通常利用時も特殊なことはしておりません。例外なくユーザーはIdPでのSAML認証とそのアトリビューションにより、Nodeへのログインに必要なフェデレーションおよび権限が割り振られています。ログイン後の作業ログはS3に保存され、ログインなどのイベントやセッション情報はDynamoに保存されています。

f:id:kengoscal:20181130145056p:plain

基本、AuthサーバーやProxyサーバーにログインできないようにしていますが、緊急時は停止させている緊急用踏み台を起動&SSH Proxyでのログインを実現しています。その場合、緊急ログイン用の秘密鍵が作業端末上にあると元の木阿弥ですので、当社ではKryptonと呼ばれるスマホ上のセキュアストレージに秘密鍵を入れるソリューションを使っています。これを使うと、ログイン時にスマホに利用可否通知がきて、そこでアクションをとることで初めてSSH鍵認証が完了します。原理上、秘密鍵はそこから取り出せないので、スマホを盗難されない限り安全です。 f:id:kengoscal:20181130142810p:plain

Krypton | Let's make two-factor easy & secure

プロビジョニングはConsul, Ansible, Teleportの組み合わせでしています。Nodeの方は既存の枠組に乗りAnsibleとConsulを使っています。ProxyおよびAuthサーバーはTerraformでAWSのリソースもTeleportの設定ファイルもプロビジョニングしています。

f:id:kengoscal:20181130144546p:plain

改善ポイント

デバッグ・デプロイの効率化

ログインイベントのデバッグをする場合、イベントログのはいってるDynamoを見るわけですが中々追いづらいです。また、構成管理権限を基本もっているので、デバッグのためにDynamoに入りたくないということもあります。当社の場合、Datadogを使ってメトリクスやログを収集しているので、今後はDatadogに寄せる予定です。

また、業務分掌(Segregation of Duties, SOD)を真面目にやろうとすると、Terraformでプロビジョニングしている設定ファイルとシェルスクリプトがuserdataのサイズ上限に引っかかってきます。また、デプロイ作業そのものもマニュアルな部分が多いです。よってそこは、同僚であるSREの @sion_cojp *2 の仕事を参照して、Fargate/Docker/SlackBot/Makeをもりもり使うイカしたものを作って行こうと思います。

f:id:kengoscal:20181130150015p:plain

sioncojp.hateblo.jp

業務分掌が辛いんじゃぁ〜

Teleport EntepriseはRBAC(Role Based Access Control)が可能です。しかしながら、あくまでもクラスターごとの設定であり、集中的な権限管理ができません*3。 真面目にSODをやろうとすると戦術の通り設定ファイルが大きくなります。各AWSアカウントごとの設定、更に言うとその中でもマイクロサービスごとに、もっというとチーム内の役割ごとに権限が異なるためです。残念ながらTeleportの設定はあくまでもYaml記述ですので、if stg && account { if manager { allow root login} else { allow normal login } } のような制御ができません。これに対するしくみは現状ありませんが、k8sClusterRoleBinding を真似して、コントロールプレーンのプラグイン作成のようなチャレンジをしてみたいと思っています。

f:id:kengoscal:20181130152109p:plain

当社のTeleportに対する貢献

当社はただTeleportを使うだけではありません。積極的に欲しい機能やバグ修正をPRするなど、コミュニティへの貢献もしております。

Support regex expression for node_labels by ken5scal · Pull Request #2206 · gravitational/teleport · GitHub

Fixed the bug in the Web GUI (send too much size data) by paihu · Pull Request #2320 · gravitational/teleport · GitHub

残念ながらまだコントリビューターにはなれていませんが(cherry-pickされてる)、OSSであるからには開発者と利用者が協力して継続的なサービス改善に挑んで行きたいと思います。

FOLIOでは仲間を募集しています

ビジネスとそれを取り巻く環境(含むセキュリティ)は日進月歩です。ビジネスサイドや開発者が圧倒的な進化を遂げて新しいサービスと価値を世に広めようとするなら、情シスやセキュリティもそれに適応していくことが求められます*4

そのためには、最新の技術動向やOSSを含む製品選定が求められていくことになりますが、時には文字通りコミットすることで技術やOSSそのものをドライブすることも今後の情シス・セキュリティチームに必要になってくると思います。 そういったアクティブな情シス・セキュリティ活動を当社でやってみたいかたは Twitter@ken5scal に気軽にDMください :)

2日目は @mura-mi さんです。

*1:CNCFのシルバーメンバーでもあります

*2:こいつはすごい

*3:Trusted Clusterはクラスター間の信頼なので集中管理はできない

*4:もちろん原則を忘れずに

Go Global参加レポ

go-global.connpass.com

上記のイベントにシュッと参加してきたのでレポ。

tldr

現地で働いてるかたのナマの声などがきけて為になった。 leetcode頑張ろうと思いました。DroidKaigiが終わったら。

各セッション

「メルカリにおける技術者採用方法の変遷」とスマニューの「コーディング試験Codility運用の実態と実績」は遅刻したためレポなしです...すみません...

[リクルート] コードテストでtrack.runを使ってる話と採用フロー by @yosuke_furukawa

  • インターンのコードテストでtrack.runを利用している。
  • DB操作、HTTP API送信・受信、アルゴリズム問題、数学問題が題材
  • 時間切れになってしても、回答の中でアピールすることが可能
  • 中途面接の場合は、職務履歴書から質問を考えて、そのかたが何を学んだかにフォーカスする。自分の成長の場ともしている

[インディーゲーム開発者]:付け焼き刃でベイエリアの面接を突破するたった一つの方法 by @daigo

  • ホワイトボード面接が苦手
  • なぜなら通常の業務では鍛えられないスキルだから(Homebrewの作者も落ちる)
  • とはいえ、変な人を入れるよりマシ
  • 電話面接よりもマシ
  • tips:
    • 記述量の少ない言語を選ぶべし
    • 大枠の方針を決めるべし
    • Big-O Complexityの理解をしていれば標準関数を使っても問題ない
    • ホワイトボードでの練習をする
    • ホワイトボード面接中は常にコミュニケーションをするべし
    • 基本はアルゴリズムだが、ゲーム計だと線形代数・3D数学、経路探索、当たり判定のための円や線分もでる
    • LeetCodeを解いて、過去問になれる
    • 搦手だとCEO/CTOに気に入られたり、業務委託からはじめたりする手段がある

コーディング面接を受ける際の Tips by @thagikura

  • ホワイトボード面接苦手税
  • オンライン面接はIDE利用不可だが、易しめ
  • オンサイトはホワイトボードで、コード以外にまれにアーキやデザインに関する題材もあった
  • 時間は貴重
  • 30min out of 45minくらいしかコードを書く暇がない
  • 解決法を思いつくのはポイントの1つ
  • 早く終われば終わるほど、自己アピールタイムも増える
  • やはり記述料がすくない言語のがいいが、省略してもよいという面接官もいる
  • メソッド分割も大事で、前提条件に特定のメソッドがあるということにしてもよい
  • データ構造やアルゴリズムが大事

QuipperのWebエンジニア採用におけるコードて

  • 今は1問あたり2hrほどの問題を3つ家で解いてもらっている
  • 言語はRuby/JS
  • もともとは1つのアプリまるまる作ってもらってたが、それだと時間がかかりすぎた
  • したがって方針を1) コードテストはなくさず 2)要素技術のみを解いてもらい 3)アルゴリズム問題はださない、ことにした
  • そうすることで2week -> 3dayのプロセスにした

speakerdeck.com

人生出始めて外資の会社を受けてみた by @ganezasan

  • 日本のコーディング面接は、予備動作がなく、面接の場でいきなり題材がでてくる
  • また前提条件がざっくりしていることが多い

テックインタビュー裏表 by @mogutan88

  • 一時期、学歴詐称が通るくらいゆるい基準だったことがある(というのが面白かった)

グローバルIT企業での働くまで・働いてみての学び by @daikikohara

  • JDは熟読するべし
  • 実務経験3年はCS1年分の学位に相当
  • Cover LetterはLinkedInのプロファイルが充実していればいらない

FIDO/WebAuthNにおけるAndroid SafetyNet AttestationとKey Attestationの違い

TL;DR

  • AndroidのSafetyNet Attestation APIとKey Attestaionの違い
  • 中身のレベル: ドキュメントを読んだレベル

背景

FIDO/WebAuthN in Androidの文脈で、SafetyNet Attestation API とKey Attestationの違いってなんだっけ?というところから始まっています。

SafetyNet Attestation API

SafetyNet Attestaion APIのチェック項目

アプリがインストールされた端末のHardware/Software情報を分析し、端末の改ざんがないかチェックするAPIです。 APIを叩くことでAndroid Compatibility Test Suite(CTS)というOEMベンダーやHWプラットフォーム間で互換性を担保するためのテストスイートの結果から判定されます。「WebAuthN 8.5 Android SafetyNet Attestation Statement Format」のVerification Procedureに ctsProfileMatch 属性のチェックを要求されていますが*1、これがテストスイートの判定結果です。値がtrueであれば、root化などの改ざんされた痕跡がないことが保証されます。

f:id:kengoscal:20181125022046p:plain

*2

しかしながら、CTSにパスしたからといってAuthentictorにTEEを使っていることは保証されません。つまり、入札要件にHardware-backed Authenticatorを要求される場合、通らない事態が起こりえます。例えば、米国では政府機関の職員はハードウェアベースのAuthenticatorを使うことが強く推奨されております*3が、これに批准するのはSP800-63-BのAAL3もしくはFIDOのAuthenticator Level 3 *4 になります。

Secure Element つまりHALをインターフェースにしたTEEのようなTamper-resistantなハードウェアをチェックする機構がSafetyNet Attestation APIにも実装されたものの*5Android 9(Pie)からでしか使えません。

チェックの経路

CTSは公開されていますが、アプリ開発者はCTSをUSBでつないだ端末もしくはエミュレーターでしか走らせることができません。つまり、ユーザーが認証情報を登録したいアプリおよびインストールされたローカル端末内でAttestationが完結するわけではありません。ドキュメントにある次の図が示すとおり、①アプリがGoogle Play Servicesの中にある SafetyNet Attestation API を叩いて、②Google Play ServicesがGoogleのBackend APIに対して更にリクエストを投げる形になります。

f:id:kengoscal:20181124225451p:plain *6

こ子でのポイントはネットワーク通信がクライアントとGoogleのBackend APIおよびFIDOサーバーの間で計2回のネットワーク通信をすることになります。FIDOサーバーへの連携はまだしも、Google Backend APIへの互換性チェックは「10 things you might be doing wrong when using the SafetyNet Attestation API」にある通り多くの帯域や電力を消費すること*7 になるため、ユーザーにとって嬉しいことではありません。

Key Attestation

さて、Android 7(Nougat)ではKey Attestationが追加されました。「WebAuthN 8.5 Android SafetyNet Attestation Statement Format」*8にも書かれていますが、こちらとSafetyNet Attestation APIがある場合はこちらを使うほうがベター(SHOULD)です。これは次の点からだと自分は思います。

  1. Authenticatorの真正性を確認できる
  2. 登録に必要な情報以外を集める必要がない
  3. 通信量を減らせる

Authenticatorの真正性を確認できる

Google Play Storeがプリインストールされた端末の初期バージョンがAndroid 7の場合、attest_key()を呼び出しTEEにあるAttestation Keyをつかうことで、 keyPairGenerator.generateKeyPair()で生成される認証(Assertion)用鍵に対して署名ができます。Attestation Keyは工場出荷前にTEEに埋め込まれたものなので登録リクエストの証明書チェーンを検証することで、FIDO認定のAuthenticatorが使われたか判断することができます。

登録に必要な情報以外を集める必要がない

FIDOはプライバシーも考慮した仕様です。そのため、個人を特定できないように、大量生産したAuthenticatorごとに共通したAttestation Keyを埋め込んでいます*9。せっかく、そのような設計にしているのに、SafetyNetではその過程で窃取可能な情報の範囲を端末全体に広げてしまっています。その先がGoogleとはいえ、FIDOのプライバシーポリシーとしては望ましくないでしょう。

通信量を減らせる

GoogleのBackend APIに通信するとき、必ずしも端末の完全性に必要な情報のみを送るわけではありません。互換性チェックのため、様々な情報を多くの帯域や電力を生贄に消費することになります。FIDOはIoT分野の認証も狙ってるようなので、地味に大切じゃないかなぁ。これをKey Attestationにすれば、通信量はCRL関係の通信のみに限定されます。

といったことから、Androidアプリ開発者は次のようなフローで2つのAttestationを使い分ける形になると思います。試しに書いてみたので、実機での検証はまだです。

// Generate a Key Pair
KeyPairGenerator keyPairGenerator = null;
keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
AlgorithmParameterSpec params = new KeyGenParameterSpec.Builder("Key1", KeyProperties.PURPOSE_SIGN)
    .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
    .setDigests(KeyProperties.DIGEST_SHA256)
    .setUserAuthenticationRequired(true)
    . setUserAuthenticationValidityDurationSeconds(5 * 60)
    .setAttestationChallenge("challenge".getBytes())
    .build();
keyPairGenerator.initialize(params);

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey privKey = (SecretKey) keyStore.getKey("Key1", null);
SecretKeyFactory factory = SecretKeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo = (KeyInfo) factory.getKeySpec(privKey, KeyInfo.class);

if (keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware()) {
    // build Android Key Attestation Statement Format
} else {
    // Send a request to SafetyNet Attestation API
    // Build Android SafetyNet Attestation Statement Format
}

以上。

おまけ

AttestとCertifyの違いについて一時期ものすごく気になっていたのですが、最終的に次の様な使い分けになると自分の中で結論を出しています。

  • Attest: 何かしらが本物であることを断言すること。対象が美術品などであれば鑑定人が必要で、対象が証言などであれば証人(及び証人の署名)が必要。
  • Certify: 何かしらが基準に沿ったナニカであること。

なのでITにおける認証情報の登録の文脈で、例えば製造元の秘密鍵によって証明書チェーンが構築されるFIDOでは登録プロセスの一部でAttestされていると言えるのではないでしょうか。そもそもがここらへんは欧米発祥の概念であるので、しゅっと一言の日本語にするのは難しいと思いました。

...っていうことを国際法律事務所にいる弁護士の友人に聞いたところ「ん〜、同じじゃない?」と言われたので、拘ることを辞めました。

余談

最近、アウトプット疲れを起こしていたのですが、その一因として気負いすぎていたことがあると思いました。砕いてい言うと、発表・講演とブログ上でのアウトプットに対して同じ情報量と質を自分に対して求めていて、それが重荷になっていたようです。よって、改めてアウトプットの目的の1つである「自分の思考の整理をすること」に立ち止まり、つまりブログでは自分が理解できるレベルで満足する方向に決めました。 あと、発表や講演をする目的である「他の人に知見を共有する」には、それなりに聴講者のことを考える労力に加え、情報のまとめ・削減・制御が必要なので、その一部を構成する内容を順次公開していったほうが最終的な編集工数が減ると見込みました。

余談の余談

自分は文章化や可視化がめちゃくちゃ苦手(=それなりにするのに時間がかかる)ので、まずはバシバシ数を出して慣れようと思いました。

技術書典5で新刊を出します(セキュア旅団 - 「あ10」

きたる技術書典5で「No Security No Life」 という新刊を出します。ブースは「あ10」です

f:id:kengoscal:20181008010229p:plain
新刊

f:id:kengoscal:20181008010426p:plain

各章を紹介します。

PowerShellによるWindows APIプログラミング by @gr4vit0n

Exploit-DBでARM分野の掲載数が世界一の @gr4vit0nさんが書くPen tester向けのPowerShell編です。「ペネトレーションテスターのためのPowerShellの基礎」の続編で、攻撃に必要な基礎部分をWindows APIに特化して解説します。

転生したらWordPressでインシデント対応の担当者だった件 by @ym405nm

WordPressまわりの脆弱性の権威である @ym405nm のなろう系ラノベデビュー作です。ある日キッティング担当のたかし君が目を覚ますとWordPress担当者になっていた!そこから急にインシデントにモテモテに..

Cracking ASR - 音声認識システム by @bbr_bbq

BlackHat Arsenalもはや常連といっていいセキュリティ周りの機械学習マン @bbr_bbq が音声認識システムに対する悪意ある偽音声データの生成手法とその対策 を論文を紹介しながら語ります!

FAPI the Security: the 2nd by @ken5scal

FAPI Read and Write Profileの仕様について語ります。OIDC Hybrid Flow, ID token, MTLS, JWT/JWSについてお話します。Open Bankingなどに興味がある人は是非読んでくれよな!

以上、「お、なるほど!こういうセキュリティもあるんだな!」とWowをお届けする4章をまとめた「No Security No Life」/1000円を #技術書典5 でオール電子書籍で配布します。既刊もあるので、是非そちらとあわせてご検討ください

Financial APIs Workshop 2018 と Japan/UK Open Banking and APIs Summit 2018参加レポ #fapisum

Authlete社の創業者 川崎さんにお招きいただき次の2つのイベントに参加してきました。 (川崎さん、ありがとうございます!)

⁃ 7/24(火): Financial APIs Workshop 2018
⁃ 7/25(水): Japan/UK Open Banking and APIs Summit 2018

両日とも満席であり金融機関向けAPIやFAPIへの関心が高まっていることを実感できる2日間でした。 内容は7/24は技術者を対象にした、7/25はよりエグゼクティブを対象としたThe Open Banking Implementation Entity(OBIE)やFAPIを中心としたセッションになっていました。本ブログはその2日間をまとめたものになります。

OBIE概要

金融機関に預けられた取引履歴や本人情報などの金融データはユーザーのものになりますが、従来は金融機関がそれらをある意味、勝手に利活用していました。それを本来の所有者であるユーザー自身が制御できるようにすべし。ローコストで機会を増やすべし。そういった考えからオープン銀行APIの標準やセキュリティやセキュリティアーキテクチャを策定している in イギリスがOBIEです。 OBIEは所属団体が 継続的に仕様に満たされた実装されていることを保証 することで、一時的に準拠可能な企業を量産するのではなく、エコシステムを築くことを1つの目標としています。

OBIEの標準は大まかに4つのカテゴリに分けられます。

  1. Identity: 信頼されたOBIE参加団体と顧客(APIクライアント?)に関するリストとAPI。アプリ登録や登録された銀行やFintechの情報(含むJSON形式のデータ)のみならずSwaggerファイルも置かれているようです。
  2. Reference Data: 銀行の商品や説明(eg ATMの場所)といったオープンにすべきデータに関するAPI
  3. Users Data: 口座や支払い情報に関するRead/Write API

  4. Security: 認可や認可の委譲にかんする同意を含めたセキュリティ標準

OBIEは2016年に発足したばかりですが、2018~2018は様々な仕様の追加・変更があるようです。 AIS(Account Information Services)やPIS(Payment Initiation Services)のPSD2(※)口座や通貨への対応、CIBA(Client Initiated Backchannel Authentication Profile)によるユーザー同意とクライアントが認可トークンを取得するデバイスをDecoupledする仕様、失効通知…などがもりもりです[1: p9]。

※ 銀行によるオープンAPIを事実上義務付けた決済サービス指令のv2

こちらを整備していきつつ、開発者やベンダーへのサポートを充実させていくようです[1: p.15]。

OBIEの技術スタック

全ての仕様はオンラインに公開されています[3]が、ベースはOAuth2.0[4]のフレームワークです。

OAuth2.0++

OAuth2.0についての基本的な解説もありました[9]が、基本的には@TakahikoKawasakiさんのQiita[4]を読めばおkです。しっかり理解したいのであればRFCを読むといいでしょう。ちなみに、私は両方読んでいるので完全に理解しています(していない)。 他にもある主体について「この主体はこの情報があるから真正だぞ」と主張するための情報を表現するJWT[7]についての解説もありましたが、これはRFC7519とともにAuth0が発行している”JWT Handbook”を読んで見るのもいいかもしれません。私は両方(略)。

OAuth2.0(RC674)はフレームワークです。すなわち場面やケースにあわせて、オプションを付与したり拡張することができます。逆に言うと、フレームワークのみでは十分出ないケースがあります。

金融APIも例外ではなく、金融機関として満たさなければいけないセキュリティの要件または ”プロファイル”になります。Nat Sakimuraさんの講演[10]によると、RFC6749単独ではプロファイルは満たせません。なぜならOAuth2.0における認可フローの各ステージにおいて、認証(メッセージ、送信者、受信者、利用者)などが考慮されてないからです。具体的に言うと、認可リクエストやレスポンスの保護といった部分が十分ではありません。

またOauth2.0では許容されていたBearer Tokenも盗難されたら誰であろうと利用可能になってしまうなどの問題もあります。そこで、従来のOAuth2.0に加えPKCE + Hybrid Flow + JWS AuthZ Request(JAR) + MTLSを拡張機能としてとりこむことで、金融機関向けのセキュリティ要件(プロファイル)を満たしています。 なお、上記の話はNat Sakimuraさんの講演ではFAPIのread/write security profileの文脈ででてきましたが、OBIE自体はそれをベースにしている[13]ので大きくずれてはないと思います。私の知る限りではOBIEでは、トークンが発行要求者とひもづいているSender Constrained TokenのうちToken Bindingについて触れてないぐらいだと思います。

このような仕様を認可サーバーをAPIで提供するAuthleteさんはver2.0で実装したようです。他にもAuthleteさんはFAPI受けスコープ属性の管理機能を作成したり、新規クライアント認証の方式を追加したり、MTLS証明書および検証ができるような機能が追加されたようです[18]。

その他OBIEの仕様・サービス

上記だけでなく次に紹介するような仕様やサービスがありました。恥ずかしながら、私は知りませんでした。

さて、OAuth2.0はRedirectを前提としたフレームワークになっていますが、EU各国では様々なバリエーションが登場しています。 例えば、POSで支払いをするクライアントがユーザーの管理下にないことを想定し、同意や認証はユーザーの認証器で、トークンの取得はOauthクライアントに分離(decoupled)するようなアプローチもあります。 また、こちらはあまりよくわかっていないですが、”認証した結果を「パスワード」として送信する[14, p.18]” というようなEmbeddedな方法もあるようです。

個人的に一番newだったのはintent registration endpointです。探してもあまり情報がでてこなかったので多分に推測がありますが、AuthZリクエストを送る前に、認可目的をサーバーに伝えるような仕様です。例えば、「Aさんに$100を送信する」行為をしたい場合、その目的をクライアント経由で送りintent_idを取得します。認可リクエスト時にはintent_idを記載したリクエストをします。こうすると例えば「同意を得るために必要な個人情報の取得」といったユースケースにも利用できるのかと思われます。

Open Banking Conformance Suite[15]も素晴らしかったです。これは先述した”所属団体が継続的に仕様に満たされた実装されていることを保証”した状態を保証します。これは、FAPIやOBIEのAPIプロファイルに対するテストだったり、IdPやFIntechなどのRPにも適用できるテストです。これにより、コストや準拠状況を一瞬で可視化できるようになります。これがあれば、各金融機関がFintech業者のセキュリティ担当に押し付けるフォーマットがそれぞれ完全にことなり評価ポイントもまちまちの全く本質的でないセキュリティチェックシート in エクセルを駆逐できるようになると思います。

そして、Open Banking Directory[16]。これ、個人的にOpen Banking Conformance Suiteと同じくらいワクワクしたがNew内容なので、詳細はもっと調べてからにしたいです。サマリーとしては、Regulators(金融庁のような監督組織?)、銀行、Fintech企業などのサードパーティが、それぞれが他のDirectoryメンバーとやりとりするためのクレデンシャル(例: 登録したアプリのクレデンシャル)や証明書およびその他属性データを登録する場所、それがOpen Banking Directoryです、多分。

まとめ

以上のように、今回の2つのイベントをひっくるんだ#fapisummitに参加してまいりました。 英国では着々と金融APIの発展が進んでいるようです。日本でも同様に整備しよりスケーラブルでセキュアな金融基盤がうまれることを願っています。

私自身もFAPI Part.1(Read Only API Security Profile)について「俺らの愛したセキュリティ」で著しました。もしよければ次のリンクからご購入してみてください。 https://booth.pm/ja/items/864595

また、技術書典5にも無事当確しました。その際にはFAPI Part 2(Read and Write API Security Profile)について書くやもしれません。その際は、是非当ブースまでご訪問ください。

Reference

[1] Ralph Bragg, Open Banking for Developers. https://www.slideshare.net/fintechlabs-io/open-banking-for-developers [2] Tasuya Kudo, Trends in Banking APIs, https://www.slideshare.net/fintechlabs-io/banking-apis-authorization-practice [3] Https://openbanking.atlassian.net/wiki/ [4] Takahiko Kawasaki, https://qiita.com/TakahikoKawasaki [5] The OAuth 20 Authorization Framework(RFC6749), https://tools.ietf.org/html/rfc6749 [6] OpenID Connect Core 1.0 incorporating errata set 1, http://openid.net/specs/openid-connect-core-1_0.html [7] JSON Web Token(JWT), https://tools.ietf.org/html/rfc7519 [8] JWT Handbook, https://auth0.com/resources/ebooks/jwt-handbook [9] Takahiko Kawasaki, OAuth OIDC Basics, https://www.slideshare.net/fintechlabs-io/oauth-oidc-basics [10] Nat Sakimura, FAPI and Beyond, https://www.slideshare.net/fintechlabs-io/fapi-and-beyond [11] OAuth2.0, https://oauth.net/2/ [12] Financial-grade API (FAPI) WG, http://openid.net/wg/fapi/ [13] Open Banking Security Profile - Implementer's Draft v1.1.2 , https://openbanking.atlassian.net/wiki/spaces/DZ/pages/83919096/Open+Banking+Security+Profile+-+Implementer+s+Draft+v1.1.2#OpenBankingSecurityProfile-Implementer'sDraftv1.1.2-OAuth2.0,OIDCandFAPI [14] Tatsuya Kudo, Trends in Banking APIs, https://www.slideshare.net/fintechlabs-io/banking-apis-authorization-practice [15] Joseph Heenan, FAPI/Open Banking Comformance, https://www.slideshare.net/fintechlabs-io/fapi-open-banking-conformance [16] Open Banking UK Identity Product, https://www.slideshare.net/fintechlabs-io/the-open-banking-identity-product [17] AUTHLETE 社、「金融グレード API」導入促進へソリューション提供開始 , https://prtimes.jp/main/html/rd/p/000000007.000024448.html [18] Justin Richer, Authlete FAPI Implementation Part 1 https://www.slideshare.net/fintechlabs-io/authlete-fapi-implementation-part-1