Gaudiy Tech Blog

Gaudiyの技術、開発組織、カルチャーについてお伝えするブログです

ECDSA署名の数学的理解とCloud KMSによる実装

こんにちは!ファンと共に時代を進める、Web3スタートアップのGaudiyでエンジニアをしている椿(@mikr29028944)です。

先日、Gaudiyではサーバーサイドウォレットの構築やEthereumにおけるECDSA署名の実装を行いました。

そこで今回は、少しニッチではありますが「ECDSA署名」をテーマに、Gaudiyの事業背景から、ECDSAの数学的な処理とコードまでを、実例をふまえてお伝えしてみたいと思います。

はじめに断っておくと、僕は大学時代にzk-SNARKsの理論を研究していたため、代数学を学んだことはありますが、この領域における専門家ではありません。なので理解が誤っている部分があれば、ぜひご指摘いただけると嬉しいです。

Web3スタートアップで働くことに興味がある方や、ブロックチェーンを業務で扱うエンジニアの方にご参考になればと思い、詳しく書いていたら1万5千字を超えてしまいました…。

以下の目次から、興味あるパートだけでもよければご覧ください!

1. GaudiyがECDSA署名を扱う理由

Gaudiyでは、ブロックチェーンを活用したファンコミュニティサービスを開発・提供しています。

そのコミュニティでは、ユーザー体験を考慮して、これまではガス代のかからないプライベートチェーン上でNFTを発行していました。それを今回、ユーザー同士でアイテムのトレード(二次流通)を行ったり、NFTとしての価値を感じられる体験を提供するために、EthereumやPolygonといったパブリックチェーン上へと書き出す(ブリッジする)機能を実装することになりました。

しかし、すべてのデジタルアイテムを、ユーザーが好き勝手に書き出せてしまうのには問題があります

なぜなら、Gaudiyではマンガ、アニメ、ゲームなどのIP(知的財産コンテンツ)公式コミュニティをつくっており、そのコミュニティ内で配布されるアイテムもIPに紐づく画像などが多いため、著作権にも関わります。なので、あくまで「許可されているアイテムのみ書き出せる状態にしたい」というのが要件としてありました。

この課題を解決するため、サーバーサイドウォレットを作成して、Gaudiyからユーザーに対して「あるアイテムに対して書き出し可能な証明書」を発行することで、管理者の署名がないとアイテムを引き出せないようにする仕組みをつくることになりました。

ここで使われている「ECDSA」による署名や検証の方法について、Gaudiyでの実例も交えてお伝えしていきます。

2. ECDSA署名とは何か

ECDSA(Elliptic Curve Digital Signature Algorithm)とは、楕円曲線DSAとも呼ばれており、ビットコインやイーサリアムの文脈では特にトランザクションの署名に使われます。

▼こちらの記事がわかりやすいです。

zoom-blc.com

ECDSAを理解するには、前提知識として「楕円曲線暗号」を知る必要があるので、まずはその概要から説明していきます。(実例だけ知りたい方は、4. まで読み飛ばしていただいても大丈夫です。)

2-1. 前提知識としての楕円曲線暗号

2-1-1. ざっくりとした楕円離散対数問題

そもそも楕円曲線暗号とは、楕円曲線上で組み立てられた暗号プロトコル全般を指します。

近年、RSAに変わる公開鍵暗号として注目されており、RSAよりも短い鍵長で同じくらいの安全性を持つという特徴があります。実際に身近で使われている例としては、デジタル放送における映像コンテンツの著作権保護技術や、ICカード、SSL/TLSなどがあります。

後ほどより具体的な楕円曲線の話をしますが、この章では簡単に楕円曲線暗号の概念を解説したいと思います。

ある地図の上でゲームのキャラクターが歩き回ることを考えてみてください。

このゲームの世界では、地図から歩いて右方向に突き抜けても、反対側から同じ角度で出てくることにします。ゲームキャラクターが歩幅{P}で原点{O}から一定な角度をつけて歩くとします。2歩進むと{2P}の位置にいます。これを10回、100回…と続けても{10P,100P, 10^{100}P}と容易に位置を求めることができます。

しかしこの世界では、キャラクターが何歩歩いたかを忘れてしまった場合、今いる位置と自分の一歩から何歩歩いたかを求めようとすると、とても難しいことが知られています。一歩{P}が決まっている時に

歩数nから現在地nPを求めることは容易だが、現在地nPからnを求めることは難しい

という関係性が成り立ちます。一般に「有限体 \Bbb{F} _ {p}上の楕円曲線上の点 nP Pが与えらた時に nを求めよ」という問題を楕円曲線離散対数問題と言います。(地図を楕円曲線として変換しています)

また、この問題を利用して、楕円曲線暗号では nPを公開鍵、 nを秘密鍵として、「公開鍵から秘密鍵を現実的な時間で求めることが難しい」ことを安全性要件としています。

(以下の参考書から例を抜粋しています)

クラウドを支えるこれからの暗号技術 | 光成 滋生 |本 | 通販

2-1-2. 楕円曲線暗号

では実際に、代数的な側面から楕円曲線上の加算と楕円曲線離散対数問題について考えます。

 pを大きな素数として、有限体  \Bbb{F} _ p上の楕円曲線は、以下のような3次方程式で定義されます。

 4a^ 3+27b^ 2 \not = 0かつa, b \in \Bbb{F} _ pとする。以下では下式の楕円曲線を Eと表します。

 
\tag{*} y^2= x^3 +ax +b 

楕円曲線上の有理点の集合の全体は以下のように定義する加法について群をなすことが知られています。

曲線上の点 Aと点 Bを足した点 Dは、点 A Bを結ぶ直線が再び曲線と交わる点 C y座標の符号を反転した点で定義されます。点 A Bが同じ点である場合は、その点で接戦を引きます。また楕円曲線上の点として、無限遠点 Oと呼ばれる仮想的な点を定義します。さらに無限遠点 Oとある点 Pの加算結果は、点 Pになると定義します。

この時、曲線上の点 Gがある場合に、上記の方法でその点を k回加算する演算(スカラー倍算呼ぶ)と、自然数 kから点 W=k \times Gを満たす自然数 kを求める演算は、容易に求めることができます。一方で、このスカラー倍算の逆演算(2点 G Wから、 W = k \times Gを満たす自然数 kを求める問題)は楕円曲線離散対数問題と呼ばれ、自然数 kの桁数が大きくなるほど解くのが難しいと言われています。

まとめると、楕円曲線暗号は、この「楕円曲線上の離散対数問題」を用いて構成される暗号のことを言います。

次に、この楕円曲線上の離散対数問題を利用したECDSAによる署名と検証について考えていきます。

2-2. ECDSAによる署名と検証

アリスが自分の公開鍵を使って、ECDSAによる署名と検証を行うことを考えます。

  1. 公開設定:有限体 \Bbb{F} _ p上の楕円曲線 Eと点 P(素位数 lの巡回群の生成元)を選びます。また、ハッシュ関数 hを選びます。

  2. 鍵生成:まずアリスはランダムに a \in \Bbb{F}^{*} _ {l}を選び、 A = aPとします。このとき aをアリスの秘密鍵、 Aをアリスの公開鍵とします。

  3. 署名:ランダムに k \in \Bbb{F} _ {l}^{*}を選び、 kP x座標を rとします。平文 mに対して、以下のように s求めて (r, s) mに対する署名とします。以下では下式を s \equiv k^{-1}(h(m) + ar) \bmod lと書きます。

     \tag{1}  s \equiv {(h(m) + ar) \over k} \bmod l

  4. 検証: u \equiv s^{-1}h(m)  \bmod l v \equiv s^{-1}r \bmod lを計算し、 x座標に関して、 \bmod lで以下の式が成り立つことを検証します。

 
    \tag{*} uP +vA = k P

 A= aPより

 
    uP + vaP = kP

楕円曲線のスカラー倍算より

 
    (u + va)P = kP

 u, vより

 
    (s^{-1}h(m) +s^{-1}ra)P =  s^{-1}(h(m)+ra)P = kP

左辺に (1)を代入して、

 
    (k^{-1})^{-1}(h(m)+ar)^{-1}(h(m) +a r) = kP

となり、右辺の kPと一致することがわかり、正当な署名であることの検証ができました。では次に、ここで定義した変数や処理を用いて話を展開していきます。

3. EthereumにおけるECDSA署名

3-1. secp256k1と呼ばれる楕円曲線

先ほどECDSA署名の処理を構築した際に a, bなどの多数の変数を用いました。これらは、なんでもかんでも自由に決めていいわけではありません。脆弱性のあるパラメータで楕円曲線暗号を構築した場合、計算量が多項式時間で解けてしまう攻撃手法SSSA法、準指数関数時間で解けてしまうGHS法などのあらゆる攻撃手法によって、簡単に楕円曲線離散対数問題が解けてしまいます。こういった攻撃手法の適応条件に合わないようにパラメータを選定する必要があります。

NIST(⽶国⽴標準技術研究所)やSECG(The Standards for Efficient Cryptography Group)と呼ばれる楕円曲線暗号の商用的な標準仕様を査定している機関が、安全な楕円曲線暗号を作るための推奨パラメータを公表しています。詳しくはSEC 2: Recommended Elliptic Curve Domain Parametersをご覧ください。

Ethereumでは、SECGが推奨パラメータとして公表している中の一つである「secp256k1」を使用しています。この楕円曲線から、公開鍵や秘密鍵の生成がされています。パラメータ T = (p, a, b, G, n, h)はそれぞれ以下の値になり、 (*)で定義した楕円曲線に a, bを代入すると以下のような方程式になります。

 
y^2 = x^3 +7

後の章で nを用いた話があるのでここで説明しておくと、パラメーターに含まれる nとは、楕円曲線上の点 Gが与えられた時に n \times G  = Oとなる正の整数であり、この n Gの位数と呼びます。群の位数、元の位数の定義などはこちらの記事がわかりやすいです。

secp256k1でのパラメータ T = (p, a, b, G, n, h)は以下のような値になっています。

Recommended Parameters secp256k1

詳しくはこちらのRecommended Parameters secp256k1セクションをご覧ください。

3-2. EthereumでECDSA署名を扱う

では実際に、secp256k1の楕円曲線上のECDSA署名がどのように行われているのかをみていきます。

詳しいEthereumにおけるECDSA署名の仕様はこちらのEthereum Yellow Paperをご覧ください。

 
\text{signature} = (r, s, v)

EthereumにおけるトランザクションはECDSAによる署名がされ、32バイトの r値と s値、1バイトの v値を連結した65バイトを署名とします。 r値と s値に関しては先ほど記述した値になり、 v値に関しては x座標が rとなる点 Rを一意に定めるための値になります。

もし v 0の場合は R y座標の値が偶数、 v 1の場合は R y座標の値が奇数を表します。 v値に関しての詳細は、後述するEIP-155と一緒に説明します。またECDSA署名が有効な場合は、以下の条件が成り立ちます。

 
\begin{aligned}
0 < &r < \text{secp256k1n} \\ 
0 < &s < \text{secp256k1n}/2 +1
 \\ 
&v \in \lbrace 0, 1\rbrace
\end{aligned}

 \text{secp256k1n}とは、前述した n \times G  = Oとなる基点 Gの位数 nのことです。 rの取りうる範囲が 0から \text{secp256k1n}まで、 sの取りうる範囲が 0から \text{secp256k1n/2 +1}まで、 v 0 1の値を取ります。

 r \text{secp256k1n}までである理由はわかると思います。なぜなら、 \text{secp256k1n}は先ほどのECDSA署名の Gの位数 lにあたり、計算が \bmod l上でされているため、 r lを超えないことがわかります。ですが、 s \text{secp256k1n}までではなく、 \text{secp256k1n /2} +1までになっています。この理由は後述する「 sの反転」の章でEIP-2の概要説明と一緒に説明します。

また、署名から公開鍵の復元に関しては、平文 mのハッシュ値と r, s, vからリカバリできることがわかります。これに関しても後述します。

ここで記号を整理します。

  •  G:ベースポイント、基点と呼ばれる楕円曲線上の点(ECDSAによる署名と検証章の Pにあたる)
  •  h(m):平文 mのハッシュ値(ECDSAによる署名と検証章と同じ)
  •  k:署名ごとに異なるランダムで一時的な秘密鍵(ECDSAによる署名と検証章と同じ)
  •  n Gの位数 (ECDSAによる署名と検証章の lにあたる)
  •  r, s mに対する署名(ECDSAによる署名と検証章と同じ)

4. GaudiyではどのようにECDSA署名を行っているのか

ここからは、Gaudiyのユースケースを元にしたECDSA署名と検証フローを、実際のコードを添えて説明します。

4-1. 署名と検証の流れ

  1. digestと呼ばれるあるメッセージのSHA256ハッシュ化された値と、KMSに保存されているGaudiyの秘密鍵からKMSによる署名が生成されます
  2. この署名はASN.1と呼ばれる標準的なデータ構造から成るため、Unmarshalによって r, sをリカバリします
  3.  rに対する v値を計算し、 (r, s, v)を連結してそれをECDSAによる署名とします
  4. Ethereumのコントラクト上でこの署名が検証され、それによってリカバリされた公開鍵と署名を作成した公開鍵が一致するかを検証します

4-2. 詳細と実際のコード

4-2-1. Cloud KMSを使ったECDSA署名の構築

Gaudiyでは、秘密鍵の管理として、Cloud KMSを活用しています。

下記の記事にもあるのですが、プライベートキーを環境変数経由で渡す場合の問題点として

  • 秘密鍵を直接使えばプログラム以外の意図しない文脈で署名を行える
  • 秘密鍵を誰が使用したという履歴はどこにも残らない
  • 秘密鍵を直接持ち出せば退職者であっても署名を行える

が挙げられます。

zenn.dev

記事ではAWS KMS(Key Management System)を使ってこれらの問題を解決していますが、Gaudiyでは同じくEthereumの署名アルゴリズム、secp256k1をサポートしている Cloud KMS を使って解決することになりました。

Cloud KMSでは、非対称署名アルゴリズム、非対称暗号化アルゴリズムなどの様々なユースケースに対応できるように鍵のアルゴリズムを設定できます。

今回のケースでは楕円曲線署名を行いたいので、非対称署名アルゴリズムを選択し、曲線の種類をsecp256k1とします。Cloud KMS関する詳細はこちらをご覧ください。

Cloud KMSの鍵の扱いについて

まず最初にSignDigestという関数が署名全体の処理を行う関数になっています。引数には、署名者のアドレスとSHA256ハッシュ化させてメッセージを入れます。

このハッシュ化されたメッセージをAsymmetricSignRequestというオブジェクトを作成して、AsymmetricSignという関数を呼び、KMSによる署名を作成します。返ってきた値はASN.1の構造をしているのでrecoverRS関数を呼び、 r, s をリカバリします。

func (k *KMSSigner) SignDigest(ctx context.Context, address common.Address, digest []byte) ([]byte, error) {
  // KMSで署名を行うためのデータ
    req := &kmspb.AsymmetricSignRequest{
        Name: keyVersion,
        Digest: &kmspb.Digest{
            Digest: &kmspb.Digest_Sha256{
                Sha256: digest,
            },
        },
    }

    // KMSに保存されてる秘密鍵を用いて署名が作成される
    // この作成された署名は公開鍵を用いて検証することができる
    result, err := k.client.AsymmetricSign(ctx, req)
    if err != nil {
        return nil, err
    }

    // ASN.1データ構造のsignatureからrとsをリカバリする
    r, s, err := recoverRS(result.Signature)
    if err != nil {
        return nil, err
    }
 
    // 後半の処理
    ...
}

recoverRSの関数の中はこのようになっています。goの標準パッケージとしてasn1が提供されているので、単純にそのパッケージ内にあるUnmarshalを呼び出します。

// recover R and S from KMS signature
func recoverRS(signature []byte) (r *big.Int, s *big.Int, err error) {
    sig := new(struct {
        R *big.Int
        S *big.Int
    })

    _, err = asn1.Unmarshal(out.Signature, sig)
    if err != nil {
        return nil, err
    }

    // 処理
    ...

    return sig.R, sig.S, nil
}

4-2-2. sの反転について

急に sの反転についてとありますが、この話は、前述した sの取りうる範囲についてです。ECDSA署名が有効であるには、3つの条件がありました。そのひとつ s

 
0 < s < \text{secp256k1n/2 +1}

とすることが条件になります。EthereumのECDSA署名において、もし s \text{secp256k1n}の半分よりも大きい場合は s' = \text{secp256k1n} - s(この演算を「 sの反転」と呼ぶことにする)を計算し、この値を使ってECDSA署名を作る必要があります。

var (
    secp256k1N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
)

func recoverRS(signature []byte) (r *big.Int, s *big.Int, err error) {
    // 処理
    ...

    if sig.S.Cmp(secp256k1halfN) > 0 {
        sig.S = new(big.Int).Sub(secp256k1N, sig.S)
    }

    return sig.R, sig.S, nil
}

なぜ s 0 \lt s \lt \text{secp256k1n}ではダメなのでしょうか?これはEIP-2の中でこの問題が指摘されています。

github.com

EIP-2で言われている問題をそのまま翻訳すると

0 < s < secp256k1Nの範囲での任意のs値を持つトランザクションを許可すると、トランザクションの不正性が 懸念される。なぜなら、s値をsからsecp256k1N - sに反転し、v値を(27 → 28, 28 → 27)を反転させても結 果として得られる署名は有効である。

つまり、 sを反転して得られた s'から (r, s', v')を作成しても、異なる署名結果であるのに有効と判断されてしまうということになります。これについて実際に値を変化させて検証します。( v値については後述します)

前述の内容から sは以下のように求めることができました。

 
\tag{1}  s \equiv {(h(m) + ar) \over k} \bmod l

 sの反転」とは (1) sに対して、

 
s' = l -s

として s'とおきます。この s'から u'を求めると

 
\begin{aligned}
u' &\equiv s'^{-1}h(m) \bmod l  \\
&\equiv {1 \over l -s} h(m) \bmod l \\ 
&\equiv s^{-1} {s \over l- s} h(m) \bmod l \\ 
&\equiv  s^{-1} {s \over l- s} h(m) \bmod l - l (s^{-1}{1 \over l-s}h(m)) \bmod l \\
&\equiv s^{-1}{{s-l} \over l-s }h(m) 
\bmod l \\
&\equiv s^{-1} \lbrace -1  \times ({l-s \over l-s}) \rbrace h(m) \bmod l \\
&\equiv -s^{-1}h(m) \bmod l
\end{aligned}

となり、 u' uの関係は以下のようになります。

 
u' = -u

 vについても同様で、 v'= -vとなり、 u', v'から

 
\begin{aligned}
u'P +v'A &= -uP +-vA \\
&= -(uP+ vA) \\
&= -kP
\end{aligned}

点PとQのx座標の値は同じ

となるので、楕円曲線上の点のマイナスは y座標の正負をさせるだけで x座標の値は変わりません。

つまり、 (*)は両辺の x座標の点が同じかどうかを検証しているので、反転させた s'で評価をしても同じ検証結果が得られます。

そのためEIP-2では sの範囲を 0 \lt s \lt \text{secp256k1n}/2 +1に制限し、もしこの範囲外に sがある場合は、その署名を無効することでこのような問題を防いでいます。

4-2-3. v値について

 r, sをリカバリできたら最後に v値の計算です。 v値は r x座標の値とする曲線上の点を一意に定めるための値でした。 v \in { 0, 1}の範囲で (r, s, v)の有効性を検証し、有効性が示された時の v値がECDSA署名に含まれます。

今では v値が 0, 1の場合は古いバージョンとして存在していて、それに 27を足した 27, 28 v値として署名に含まれます。また v値についてメインネットやテストネットなどのネットワークを区別するために、chainIDを含めた v値がEIP-155で提案されています。今回はこの説明はしませんが、詳しく知りたい人はこちらをご覧ください。

 v 0 1のどちらかで正しい署名が作成できるので、2回検証を回して、それによってリカバリされるアドレスと署名者のアドレスを比較して同じ場合に、その値を v値にして最後に27を足して、署名の完成とします。

func (k *KMSSigner) SignDigest(ctx context.Context, address common.Address, digest []byte) ([]byte, error) {
    // 処理
    ...

    sig := make([]byte, 65)
    // r値
    copy(sig[:32], r.Bytes())
    // s値
    copy(sig[32:64], s.Bytes())
 
    for _, v := range []int{0, 1} {
        sigv := append(sig, byte(v))
        publicKey, err := secp256k1.RecoverPubkey(digest, sigv)

        if err != nil {
            return nil, err
        }

        verified := crypto.VerifySignature(publicKey, digest, sig[:len(sig)-1])
        addrA := common.BytesToAddress(crypto.Keccak256(publicKey[1:])[12:])

        if (verified && reflect.DeepEqual(addrA.Bytes(), address.Bytes())) {
            sig = append(sig, byte(v))
            break
        }
    }

    sig[64] += 27

    return sig, nil
}

以上、EthereumにおけるECDSA署名の作成方法について実際のコードを交えながら見ていきました。最後に、この得られた署名から公開鍵をどのようにリカバリするかを考えます。

4-2-4. ECDSA署名から公開鍵のリカバリ

署名の検証に関してはコントラクト上で行われます。ECDSA.recover によってアドレスが得られるので、得られたアドレスと署名者のアドレスを比較します。(この関数ではECDSA署名から公開鍵が得られ、内部でEthereumのアドレス形式に変換されています。)

address recoverdAddress = ECDSA.recover(digest, voucher.signature);
require(signerAddress == recoverdAddress, "address does not match");

実際にどのように公開鍵がリカバリされているのか見ていきます。

 r vから署名の際に選んだ公開鍵が一意に特定でき、それを Rとおく。

 
R= (r, y) = (u_1 + u_2a)P

 Rと署名とハッシュ化された平文 mに対して以下のように計算すると、

 
\begin{aligned}
Q &= r^{-1}(sR- h(m)P) \\
& = r^{-1}\lbrace s(u_1+u_2a)P - h(m)P \rbrace \\ 
&=r^{-1}\lbrace skP - h(m)P \rbrace \\
&= r^{-1} \lbrace {(h(m)+ ar) \over k } \times k P - h(m)P \rbrace \\
&= r^{-1}arP \\
&= aP
\end{aligned}

となり、公開鍵が導出されます。つまり、署名が正しければ導出された公開鍵と署名に使用した公開鍵が一致することがわかります。

実際 R x座標の rが満たすべき条件というのがあり、このSEC 1: Elliptic Curve Cryptographyで説明されています。詳しくはそちらをご覧ください。

以上より、ECDSA署名の作成と検証することができました。

5. さいごに

今回は、楕円曲線暗号の概要とCloud KMSを用いたECDSA署名の作成・検証方法をコードと一緒に見てきました。

冒頭にも書きましたが、大学で代数学を勉強した程度なので理解が間違っている部分等あるかもしれません。なので、もしそのような箇所があればぜひご指摘いただけると嬉しいです。

Gaudiyでは、このようにブロックチェーンが絡んだ実装もあれば、普通のWebアプリケーション開発の実装もあります。個人的には好きな分野なので、興味ある方いたらぜひお話ししたいです!

meety.net

ブロックチェーン知識は不要? 採用面談でよくあるQ&A集

f:id:hanahanayaman:20220401170428p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしているkei(@kei32bit)です。

Gaudiyの採用スタンスや具体的なスカウト手法についてはこれまでもご紹介してきましたが、今回は、実際のカジュアル面談や採用面談でエンジニアの方からよく聞かれる質問について深くフォーカスしていきたいと思います。

ブロックチェーンを扱っていると聞くと「何か特殊な経験が必要なのでは?」と思われる方が多いと思いますが、本記事では

  • 事前にブロックチェーンの知識を持っておく必要はない
  • ブロックチェーンを扱う企業にはレイヤーの違いがある
  • 重要なのはソフトウェアアーキテクチャの原則に基づいた開発経験

をお伝えできればなと思います!

1. ブロックチェーンって実際どういう風に業務で使われるの?

まずはじめに、実際のプロダクト開発でブロックチェーンをどう使っているの? という質問がよくあります。

Gaudiyのプロダクトは「ブロックチェーン技術を感じさせないような作り」になっているので、外から見るとピンと来ない方が多いかもしれません。

Gaudiyのプロダクト例 techblog.gaudiy.com

現在、GaudiyではプライベートチェーンでNFTを発行していますが、このNFTを発行する際にチェーンに書き込む処理の部分でブロックチェーン技術を利用しています。

が、それ以外のところでは、現状はブロックチェーンに関わる開発はあまり存在しません

というのもGaudiyはブロックチェーンを扱う企業ですが、アプリケーションレイヤーを扱っているので、ブロックチェーン自体の開発をごりごり推進する企業ではないからです。

f:id:kei32bit:20220401121006p:plain
ブロックチェーンにおけるアプリケーションレイヤー
ref. https://m13.co/article/crypto-and-the-consumer-the-road-ahead

アプリケーションレイヤー層にあたるGaudiyでは、ブロックチェーンはあくまでも数ある技術のひとつであり、ブロックチェーンを使わずに開発をするケースの方が多いです。

2. ソフトウェアアーキテクチャの考え方ってブロックチェーン業務でも使えるの?

結論からいうと、ソフトウェアアーキテクチャの原則に則った開発をGaudiyでは重要視しているため使えます。むしろ、開発する上でこちらの方がとても必要な考え方だと思っています

ブロックチェーン技術にはいくつか課題があるのですが、良いUXを提供するためにはソフトウェアアーキテクチャの原則に則った解決策を試行錯誤することが求められます。

具体例でいうと、以前、大量のNFTを発行するプロジェクトにて「NFTの発行が遅延しても、UXを損なわずにユーザーへのNFT配布をどう実現するか?」という課題に直面しました。

ブロックチェーンに書き込む(=NFTをmintする)際に遅延が発生するということはわりと有名な話ですが、UXを損なわずにユーザーがNFTを取得できる、という体験を提供するには工夫が必要でした。

この際のアーキテクチャ設計では「遅延配布」「非同期」といったワードをもとに、「NFTを書き出す処理だけTask Queueを使って非同期的に処理しつつ、ユーザーの受け取り画面にはメタデータ(画像など)を先に返却する」という解決策を選択しました。

ユーザーに対してはNFTの画像データを先に受け取ってもらうことでUXを向上させる、という目的を達成しつつ、非同期的に遅延配布することでNFTとして配布するという機能要件も達成しました。ですがここで、また新しい課題に直面しました。

それは、非同期処理を行うことで、nonce(ブロック生成時に必要な32bytesの数値。この数値が被ってしまうとブロックが生成できずに詰まってしまう)の制御が難しくなるという課題です。

これは非同期処理で制御せずに並列処理を行ってしまうと、nonce値が被ってしまう恐れがあるからです。

f:id:kei32bit:20220331210351p:plain
並列処理

この課題を抽象的に捉えると「直列処理」「排他制御」といったワードに変換できるので、当時は非同期処理の中で「直列処理で制御する」「並列処理を用いつつ、nonce値の予約を行うことで値の衝突を制御する」といった解決案を出すことができました。

f:id:kei32bit:20220331210412p:plain
直列処理

まとめると、今回の課題であった「NFTの発行が遅延しても、UXを損なわずにユーザーへのNFT配布をどう実現するか?」の解決策としては、以下の2点について抽象的に課題を捉える必要がありました。

1. NFTの書き出しが遅い => 遅延対応、非同期処理といった一つ上の抽象概念として課題を捉える

2. nonceの数値が被らないようにNFTをmintしたい => 並列処理ではなく直列処理で扱う、nonce値の事前確保を予約システムになぞらえて排他制御を加える、といった上位概念の解決策を当てはめてみる

具体例が長くなってしまいましたが、課題に対して事象を抽象化する思考とソフトウェアアーキテクチャに則った開発経験があれば、ブロックチェーン特有の技術課題にも対応できると考えています。

3. ブロックチェーン技術のキャッチアップってどれくらい必要?

さいごに、非常によくいただく質問ですが、結論からお伝えすると、入社前からブロックチェーンのキャッチアップは必要ありません

もちろん業務内容に応じてブロックチェーン技術の勉強が必要になりますが、Gaudiyでは以下のような文化があるため、業務内でのキャッチアップが可能です。なので、事前知識といったものは必要ありません。

3-1. ペアリサーチ

ペアプログラミングという開発手法がありますが、Gaudiyではリサーチ業務でもペアリサーチという形で取り入れています。

主に有識者とペアになってリサーチをするのですが、どんな内容でもラフに質問できるので、ブロックチェーンを学びながらリサーチを進めることができます。画面を共有しながら「なぜこの技術を調べてるのか」だったり「Twitterではこのあたりの有識者の方のコメントが勉強になる」だったり、自身のリサーチ力の基礎づくりにもなります。

以下の画像は、ペアリサーチをした際に異なるチェーン間でのスワップの仕組みについて順序を追って説明したときの図です。

f:id:kei32bit:20220331090818j:plain
例) NEARにおけるスワップの説明

Gaudiyでは現在、NFTをプライベートチェーンで発行・配布していますが、今後様々なパブリックチェーンにNFTを書き出す仕組みを進めており、「NFTを書き出すとは具体的にどういうことなのか?」を図を共有しながら説明したり質問を受けたりしました。

技術選定と同じで「なぜこの(ブロックチェーン)技術を使うのか」「メリット・デメリットはなにか」「ユーザー体験を損なわないか」といった議論は、ブロックチェーン技術を使った開発でも必須です。その前提知識の共有には、時間を費やしてしっかり理解する、というポリシーを持っています。

3-2. 超守-破離

「超守-破離」とは、Gaudiyの造語でCredo(行動規範)のひとつにもなっています。意味としては「まず先人の教えや原理原則に基づいた事例を学び、その上で新しいやり方がないか見つけ出す」といったものです。

  • 議論を始める前に、原理・原則や先人の事例をリサーチする「超守」を徹底する。
  • 過去の経験に過信せず、常に今のやり方を疑い、アンラーニングする。
  • 超守の上で、新しい概念や方法を導入し、積極的に新たな価値を生み出す。

どんなプロジェクトでも、新しい技術を使用する場合は必ず「超守」する時間をとるため、その中でブロックチェーン技術がどう使われるのかをキャッチアップできます。

具体例を挙げると、以前Gaudiyで「NFTのメタデータをどうやって生成するか?どこに保存するか?」を議論するケースがありました。 現在プライベートチェーンで発行・配布しているNFTを、今後パブリックチェーンに書き出す際に、メタデータ(画像など)をどこに置くかを前もって調査する必要があったからです。

この際も「超守」と呼ばれるリサーチの時間を取り、「そもそもNFTの資産性とはなにか?」や「オンチェーン/オフチェーンの定義とはなにか?」といった「NFTの資産性とメタデータがどう紐づくのか?」というテーマで調べました。

「超守」する際には必ず他メンバーとディスカッションしながら進めるため、何を調べれば良いのか分からないといった状況にならずに、リサーチの方向性について議論しながら進めることができます。

4. さいごに

今回は、ブロックチェーンを扱うスタートアップとして、エンジニアの方からよくいただく質問についてご紹介させていただきました。

冒頭でもご説明した通り、Gaudiyではブロックチェーンを扱っているものの、アプリケーションレイヤーでの開発を行っているため、ブロックチェーン自体をごりごり開発しているわけではないです。

ブロックチェーン特有の知識などは入社前には不要ですし、実際にエンジニアの約半数は入社後にペアリサーチなどを通じてキャッチアップしています。

ブロックチェーン企業の間にも扱うレイヤーの違いがあるため、一概には言えませんが、ブロックチェーン企業への応募に対してハードルを感じているエンジニアの方々にご参考になれば嬉しいです。

もっと詳細が知りたい、という方はぜひMeetyでお話しましょう!

meety.net

Gaudiyの技術選定などについて知りたい方は、以下の記事もご参考ください。

techblog.gaudiy.com

ブロックチェーンの勉強を始めてみたい方は、こちらもどうぞ。

techblog.gaudiy.com

Gaudiyのプロダクトってどうなってるの?

f:id:hanahanayaman:20220325141028p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでプロジェクトマネージャーをしている小川(@zheye)です。

Gaudiyのビジョンや事業、技術などについてはこれまでもご紹介をしてきましたが、「実際、どんなプロダクトをつくっているの…?」という声をよく伺います。そこで今回は、Gaudiyの提供するプロダクトの中でも、コアとなる「ファンコミュニティ」にフォーカスしてご紹介してみたいと思います。

実際のUXやブロックチェーン技術などについても触れてますので、よければご一読ください!

1. なぜコミュニティをつくっているのか

Gaudiyでは、エンタメ企業の課題を解決するため、ファンの熱量を最大化するWeb3時代のファンプラットフォーム「Gaudiy Fanlink(ガウディ ファンリンク)」を開発していますが、そのコアは「ファンコミュニティ」です。

f:id:hanahanayaman:20220325114415p:plain

スマホ版ファンコミュニティ

Gaudiyのコミュニティの特徴としては、熱量の高いファンが集まり、ファンが創作・応援などの活動をしてIPを盛り上げ、それに貢献したファンにも還元される。その循環が回って経済圏を形成できることにあります。

Gaudiy Fanlinkのビジネスモデル

そのため、ファンの方々が集まり、自律的に創作・貢献・還元を行える場所として、居心地がよく・活動しやすいコミュニティづくりをめざしています。

私たちのミッションは「ファンと共に、時代を進める」ことです。将来的には、エンタメに限らず、なにかしらに熱量を持つ人々(=ファン)と一緒に時代を進めていきたいと考えていて、それを実現するための要素としてコミュニティがあります。

またビジネスモデルの観点では、IPコンテンツを保有する企業からお金をいただいています。熱量の高いファンを集めて、IP横断のユーザー基盤を持てるようにすることで、プロモーションやマーケティングへの活用や、デジタルコンテンツの販売、サービス連携などができるようになっています。

(今回は割愛しますが、エンタメ業界の課題背景については、以下のnoteをご参考ください。)

note.com

では早速、どんなプロダクトになっているのかをご紹介していきます。

2. ファンコミュニティの特徴とUX

ファンコミュニティの基本的な体験としては、IPコンテンツに関する投稿やチャットを通じて、ファン同士で気軽にコミュニケーションが取れることです。

その特徴としては「IP公式」「ファン主体」という点があります。

公式でありながら、「運営→ファン」という一方向的なコミュニケーションではなく、ファン主体で企画や創作などの活動ができ、双方向のコミュニケーションが生まれることが特徴です。

また、Gaudiyのバリューのひとつでもある「Fandom」な体験を提供することを大事にしています。いくつか具体例を出してUX面についてご紹介します。

2-1. ファン同士で助け合える「サポート広場」

コミュニティ内にある「サポート広場」は、ファンの方同士でわからないことや疑問などを質問し合える場所になります。

f:id:hanahanayaman:20220325114854p:plain

サポート広場での実際の投稿

通常、機能の使い方などの問い合わせには運営が対応すると思いますが、Gaudiyの提供するコミュニティではファンの方が質問に答えてくださることが多いです。

2-2. ファンの自律的な活動を支援

また、ファンコミュニティ内では、公式として認められた場で二次創作が推奨されているので、ファンアートSS(サイドストーリー)小説などがたくさん投稿されています。

f:id:hanahanayaman:20220325120506p:plain

こうしたファンアートを画集にして作者さんに届けたり、ファンの方が主催してくれたゲーム大会に協賛したりなど、ファンの方々の自律的な活動を運営としてサポートしています。(まだまだ手が回っていないところも多いので、より良い体験をお届けしていきたいです…!)

2-3. 新しいファン体験「ジェネレーティブアート」

約束のネバーランドの公式コミュニティでは、関連グッズを一定の金額以上ご購入された方に、自動で生成されるキャラクターと背景画像からなるデジタルアイテム(SNSで限定アイコンとして利用可能なもの)を配布するという取り組みを行いました。

ジェネレーティブアート自体はCryptoPunkなどさまざまな海外プロダクトで利用されていますが、国内ではまだ採用事例が少ないため、New Standardな取り組みだったかと思います。

マンガのキャラクターx背景の組み合わせで、世界に一つだけのユニークなものをいかに作れるかをめざして取り組みました。

f:id:hanahanayaman:20220325115032p:plain

技術的にはJavaScriptを用いて、草原やビーチ、洞窟などのテーマに沿って背景画像を組み合わせ、地形の高さや海や山などの素材の組み合わせのセットをランダムに配置し、キャラクターの画像を重ねることで実現しました。ジェネレーティブアートは一定のロジックで作成されているので、発行ごとに必ず再現性、唯一性が担保されます。

ジェネレーティブアートについては、ほぼ知見のない状態から1ヶ月弱で実装しなければならず、かなり大変でしたが、チームとしても一定の成果を出せたので自信につながりました。

ただ、キャラクター自体の着せ替えなどもっと表現を豊かにできる部分はあったので、生成までのユーザー体験も含めて今後より改善していきたいと思っています。

3. ファンコミュニティとブロックチェーン技術

また、Gaudiyの提供しているファンコミュニティには、DID(分散型ID)NFTといったブロックチェーン技術も活用されています。

3-1. 熱量を可視化するコインが流通する経済圏

コミュニティでは、投稿やイベント参加などのさまざまな貢献に応じて、独自のコインが手に入ります。そのコインを利用することで、IP独自のデジタルアイテムやNFTを購入することができます

f:id:xiaochuan:20220325185635p:plain

このデジタルアイテムには、公式が提供する電子書籍やイラスト原画集だけでなく、ファンの方が二次創作した小説やイラストなどもあります。

直近では現金(クレジットカード)によるNFT購入にも対応しており、過去には全く新しい方式でのNFTオークションも実施しました。

一般的なNFT市場では、価格のボラティリティが激しくファン体験を損なう可能性があるため、価格変動を抑えたり、転売を禁じたりするような仕組みも、今後必要に応じて導入していきたいと考えています。また、資産的な価値だけでなく、NFTを持っていると「二次創作の販売ができる」「特典や配当が受けられる」といったユーティリティ(実用価値)を増やしていく予定です。

※NFTに関してはQuorumというブロックチェーン基盤を利用しており、現時点ではパブリックチェーンに接続していない状態ですが、今後はコミュニティからウォレットなどの外部への持ち出しができるようにする予定です。

3-2. DIDによる「デジタルバックアップ機能」

これは、あるIPの音楽ゲームアプリがクローズすることになり、そのデータをコミュニティ内でバックアップできるようにしたものです。

長らく愛されてきたゲームが終わるのは、ファンや制作者にとってつらいことです。そこでゲームでの活動や思い出をなんとか残せないかとクライアントの方と相談し、ゲーム内のカードをNFTとしてコミュニティ内に移転し、各キャラクターのエピソード動画などを、コミュニティ内で閲覧できるようにする対応を行いました。

f:id:hanahanayaman:20220325120700p:plain

この裏側で使われているのが、DID(分散型ID)という技術です。

DID(こちらの記事で解説があります)を用いて、コミュニティのユーザーIDとゲームのユーザーIDを紐付け、コミュニティとゲーム間でのデータ連携ができていたため、今回の取り組みを実現することができました。

ゲームの終了自体はとても残念でしたが、ゲームの開発会社の方からもファンの方々からも喜んでいただくことができ、Fandomな体験を提供できました。

また、ゲームが終了しても、カードを所有できたり実際にプレイしていたことを証明できるという体験は、とても自律分散的だと思います。 将来的には、コミュニティ内でこのカードを所有することによるインセンティブや実用価値も付与していきたいと考えています。

4. さいごに

今回は、Gaudiyのコアプロダクトである「ファンコミュニティ」についてご紹介させていただきました。どのようなプロダクトをつくっているか、伝わったでしょうか?

Gaudiyではコミュニティを通じて、FandomでNewStandardな体験をさまざまに生み出しています。他にも、NFTやDIDを軸としたサービス展開も存在していますが、ベースとしてはこのコミュニティを基軸にしていくことは間違いありません。

熱量の高いファンの方に最高の体験を届け、時代を進める。そんな新しいプロダクトの開発をしてみたい方はぜひこちらからご応募ください。

www.wantedly.com

いろんな職種のメンバーがMeetyをオープンしてますので、こちらからでも!

meety.net

Gaudiy、データ分析チームを立ち上げました。

f:id:gaudiy:20220317165949p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでアナリティクスエンジニア兼データアナリストをしている星野(@mochigenmai)です。

年初に公開したブログでお伝えさせていただきましたが、Gaudiyは今年から「プロダクト主導型の組織づくり」を進めています。

techblog.gaudiy.com

プロダクト主導型の組織には、データドリブンな意思決定が欠かせません。そこでGaudiyでは、データを元にしたプロダクト改善を行い、ユーザへの適切な価値提供をしていくために、1月にデータ分析チームを立ち上げました

今回のブログでは、データ分析チームを立ち上げた背景や、立ち上げ時の課題や取り組み、データアナリストの役割などについてお伝えします!

スタートアップで同じようにデータ分析チームの立ち上げを担っている方や、データ分析チームの役割に興味のある方にご参考になれば嬉しいです。

1. データ分析チーム立ち上げの背景

GaudiyではIP(知的財産コンテンツ)を有するエンタメ企業(以下、IPホルダー)に対して、IP公式のファンコミュニティサービスを提供しています。

ビジネスモデルとしてはBtoBtoCであるため、プロダクト開発においては「IPホルダーが他のIPホルダーに」「IPのファンが他のファンに」オススメしたくなるような、toB、toC双方の視点での磨き込みや仕掛けが必要です。

Gaudiyでは今まで、メンタルモデルを深掘るなどの定性リサーチを活かしたプロダクトづくりに取り組んできました。

techblog.gaudiy.com

こうした定性分析の強みはありつつも、プロダクト主導型の組織に移行するにあたって、より定量的なプロダクトの評価・改善が必要なフェーズになってきました

また、データ分析は社内の意思決定だけでなく、IPホルダーとファンからのプロダクト評価にも直結します。そこに組織として注力していきたいという背景から、データ分析チームを立ち上げることになりました。

2. Gaudiyがデータを重視する理由

Gaudiyのプロダクト開発において、なぜデータが重要なのかについて、ファンとIPホルダーそれぞれの視点から少し説明したいと思います。

2-1. ファンにとって居心地のよいコミュニティづくり

ひとつは、ファンにとって居心地のよいコミュニティをつくるためのデータ分析です。

ファンコミュニティの分析において、参考にさせていただいたのが@kengoiwt さんのnoteです。

note.com

コミュニティに参加しているユーザーを、Leader・Follower・Active Audience・Non-active Audienceという4つのセグメントに分けます。

  1. Leader
    • リーダーシップがある
    • 何らかのイベントを企画してくれる
    • クラスタをリードしてくれる
  2. Follower
    • リーダーの企画に賛同している
    • クラスタのメンバーと共に活動を行う
  3. Active Audience
    • クラスタには所属していない
    • クラスターの活動を見守っている
  4. Non-active Audience
    • 全く活動していない

このうち、LeaderとFollowerで構成される「クラスタ」と呼ばれる小さなグループが複数存在しますが、所属するクラスタが複数あるファンの方が、コミュニティでの活動意義を感じてくれるといいます。

各セグメントではコミュニティに参加している目的が違ってくるので、データ分析を通じてそれぞれのセグメントに適切な価値を提供することで、LeaderやFollowerとして活動してくれるファンが多くなり、居心地のよいコミュニティがつくられると考えています。

2-2. IPホルダーにとってのコミュニティ開設の意義

もうひとつは、IPホルダー(クライアント企業)に、コミュニティ開設による意義を感じていただくためのデータ分析です。

Gaudiyでは、ファンのコミュニティ内の活動と、外部サービスの活動を紐付けることができるDID(分散型ID)という技術を利用して、コミュニティ外のマーケティング支援も実施しています。

note.com

IPホルダーにコミュニティを開設してよかったと感じてもらうには、コミュニティの特性を理解していただいたり、各セグメントごとのユーザ数やクラスタ数、コミュニティ外での活動の傾向といった数値を確認していただくことが大切です。

IPホルダーがそういった情報にアクセスしやすく、見やすいダッシュボードなどを作成する必要があります。

3. データ分析チームの立ち上げで生じた問題と対応

Gaudiyでは、拡張性とスピード感のある開発を行うために、データベースにFirestoreを利用していますが、データアナリストからすると大きな問題が2つありました。

ひとつは、APIを利用してBigQueryにエクスポートを行う時、マスターデータとトランザクションデータでコレクション名が同一の場合、同じテーブルに登録されてしまうという問題です。プロダクト開発上はコレクション名が重複しても問題がないので、この問題が起きてしまっていました。

もうひとつはFirestoreが非構造化データなので、分析をするときの整形処理が複雑になってしまうという問題です。

どちらもデータの整形時にミスをしてしまうと、間違ったデータを利用して分析をしてしまい、意思決定のミスリードを誘発しかねません。

これらの問題を解決するために採用したのが、dbtです。

Ubie ( @sotaron ) さんの datalake, interface, component, datawarehouse, datamart の5層構造を参考にして、各層の役割を以下のように明確化させることによって、スピード感のあるデータ分析基盤の開発と意思決定を実現しています。

  1. datalake層
    • firestoreからエクスポートされるデータそのもの
  2. interface層
    • NULLの除去
    • 日付を日本時間に変換
  3. component層
    • マスターデータとトランザクションデータが一緒になっているテーブルを分解
    • 同じテーブル内のデータを別テーブルで切り分けたいものを切り分け
    • カラムのテスト
  4. datawarehouse層
    • マスターデータとトランザクションデータの結合
  5. datamart層
    • 利用用途に合わせたデータを作成

speakerdeck.com

今後はプロダクトの開発速度を落とさずデータクオリティの担保をより加速させていくためにも、エンジニアの方とNoSQLとRDBの使い分けを進めていきたいと考えています。

4. データ分析チームの役割と今後について

現在、Gaudiyのデータ分析チームは、データアナリストとBizDevを兼務する藤原さん(@rfuj1wara234)と僕の2名体制になっています。

データ基盤の開発に加え、Gaudiyには専任のPdMがいないので、意思決定のサポートだけでなくデータアナリスト自身が意思決定を行うこともあります。

そのため、以下の4つがデータ分析チームが担う役割になっています。

  1. データクオリティ担保のためのデータ分析基盤の開発
  2. ユーザー(ファン)が求める価値の提供
  3. IPホルダーのマーケティング支援
  4. 社内での意思決定のサポート

ユーザーが求める価値の提供やIPホルダーのマーケティング支援については、他チームとこまめにコラボレーションを行いながら業務をしています。ここでは、ユーザセグメントの定義やダッシュボードの整備などをするほか、データドリブンな意思決定を行うのでPdMのような立ち回りもします。

また、社内での意思決定のサポートに関しては、上記以外の内容で社内メンバーが必要と判断したデータ分析を行います。ここでは、ただの集計依頼にならないように、データが必要な背景や期日感をヒアリングした上でサポートしています

現時点では分析依頼を受けていますが、分析基盤を整えて「データの民主化」を行えば、どんな職種の方でもすぐにほしいデータが手に入る状態を作ることができると思います。

なので今後は、SQL勉強会などを開いて、データ分析チームのメンバーがいなくてもデータドリブンな意思決定を行える状態をめざしていきたいと考えています。

5. おわりに

今回は、データ分析チームの立ち上げをテーマに、ご紹介させていただきました。

まだ走り出しのチームで、手探りで進めている部分もありますが、効率的に分析が行えるように立ち上げ初期の段階から分析基盤の開発を行っています。

これからも工夫をしながらデータへの意識を社内に根付かせていきたいと思っています。そして、プロダクト主導の組織の"羅針盤"になるようなチームにしていきます。

この記事を読んで、少しでもGaudiyのデータ分析チームに興味をもってくれた方はぜひお話ししましょう!

meety.net

Gaudiyの技術スタックや思想については、以下のブログをご参考ください。

techblog.gaudiy.com

ゼロトラストをベースにセキュリティを考えてみた

f:id:gaudiy:20220311101244p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている土居(@taro_engineer)です。

最近はバックエンドからインフラ周りを担当していますが、今回は「ゼロトラスト」の考えをベースにしたセキュリティの構築をテーマに書いてみたいと思います。

ゼロトラストの定義やセキュリティに関する説明は難しい部分もあるので、正直このテーマで書くべきか僕自身も悩みました(笑)。

ただ、今回導入を検討するにあたり、ネットを調べてもほとんど実例が見当たらなかったので、僕らが調べたことや考えたことがどなたかのご参考になれば嬉しいです。

1. Gaudiyのマイクロサービスアーキテクチャ

本題に入る前に、Gaudiyのプロダクトについて簡単に説明します。

Gaudiyでは、IPコンテンツを有するエンタメ企業に対して、ブロックチェーンを活用したファンコミュニティサービスを開発・提供しています。

このコミュニティアプリは、IPごとにカスタマイズ可能な形で複数の機能を提供しているため、バックエンドにはマイクロサービスを採用しています。

f:id:gaudiy:20220310234806p:plain

全体のアーキテクチャ構成

たとえば、決済サービス、動画配信、ゲームアプリなど、クライアントの既存サービスとコミュニティアプリを連携させています。これらの依存関係を排して、拡張性をもちながら機能提供したいという背景から、マイクロサービスを採用しました。

また、スピード感をもってマイクロサービスを構築するために、コストの高いk8sではなくCloudRunを採用して、規模の拡大に伴って移行できるような体制にしています。

2. セキュリティを「今」考えるべき理由

Gaudiyが取り扱っているのは、多くのファンを有するエンタメIPのコミュニティであり、クライアントはSony Musicさんや集英社さんなど、いわゆるエンタープライズ企業です。

これまでも拡張性の高いソフトウェア設計に取り組んできましたが、今後、さらなる事業拡大や大型IPのコミュニティ開設が控えている中で、セキュリティの観点においても早めに注力する必要があると考えていました。

この検討にあたって意識したのは、早期にセキュリティの仕組みを検討することと、プロダクト特性に合わせた選択を行うことです。

たとえば、プロダクトでなにかしらの脆弱性が見つかった場合を想定します。ここでもし、セキュリティ対策のために根本的な改修が必要となると、数週間・数ヶ月かかる可能性があります。

これは既にあるアプリケーションをよりスケーラブルにしたり、ステートレスな作りにすることが難しいのと同じ原理で、早い段階からセキュリティも設計していく必要があります。

また、社内のコンプライアンスという観点でも、人が増えることによって脆弱性のリスクは上がっていきます。あるサーバーを通じて情報を悪用する人が現れてしまう可能性は、チームが大きくなればなるほど高くなります。

こうした理由から、今後の事業拡大を見越した先行投資として、”今” から近い将来を考慮したセキュリティの仕組みを構築していくことが大事だと考えました。

その設計における思想として、今回採用することにしたのが「ゼロトラスト」です。

ゼロトラストは、最近ちょっとしたバズワードになっていると思うのですが、そもそもゼロトラストとはなんなのか。Gaudiyではなぜゼロトラストの概念を採用して、どのような取り組みをしているのかについて、お伝えしたいと思います。

3. ゼロトラストとGaudiyでの採用背景

3-1. ゼロトラストとは?

そもそも、ゼロトラストとはなにか。さまざまな解釈があり、明確に定義することが難しいワードですが、個人的にはメルペイ @kokukumaさんの「ひとつの何かに依存して、すべてを許可するのをやめること」という説明が一番しっくりきています。

(こちらの記事はアーカイブ動画を含めてとても参考になりました。)

engineering.mercari.com

またGoogleの記事では、以下のように言及されています。

ゼロトラストアプローチの中核となるのは、複雑で相互接続されたシステムの単一コンポーネントに対する盲目的な信頼は、重大なセキュリティ リスクをまねく可能性があるという考えです。

詳しくは記事内に書かれていますが、安全かどうかを確かめる仕組みを複数用意して、継続的に検証をすることが、ゼロトラストのコアな部分なのだと理解しています。

Gaudiyでは、このゼロトラストの考え方、特にBeyondProdをもとにGCPを基盤とするセキュリティの構築を行っています。

3-2. BeyondCorpとBeyondProd

次に前提知識として、Googleが提唱するゼロトラストモデル 「BeyondCorp」と「BeyondProd」についてもご紹介したいと思います。

これらは、どちらもいわゆる”ゼロトラスト”なのですが、アプローチや視点が違います。

BeyondCorpは、エンドユーザーがアプリケーションにアクセスするときの考え方・フレームワークです。具体例としては、カフェや自宅などの社外から、社内データに安全にアクセスするなどが挙げられます。

一方のBeyondProdは、マイクロサービス間・アーキテクチャ設計の考え方・フレームワークです。具体例としては、サービスメッシュやBinaly Authorizationが挙げられます。

3-3. Gaudiyとゼロトラスト

ではなぜ、Gaudiyではゼロトラストの思想を取り入れたのか。

先述のとおり、Gaudiyは事業も組織も急速に拡大するフェーズにあり、マイクロサービスアーキテクチャを採用しています。

マイクロサービスは、数十・数百のサーバーに分かれるので、その分アクセスできる入り口が複数あります。境界型のセキュリティの場合、境界を超えた先のさまざまなサーバーにアクセスできる可能性があるため、マイクロサービスとしては完全にセキュアとは言えません。

そこで今回は、「ひとつの何かに依存して、すべてを許可するのをやめる」というゼロトラストの思想の中でも、マイクロサービス間・アーキテクチャ設計の考え方である Beyond Prodをもとに、まずはアーキテクチャのゼロトラストを考えました。

一方、ゼロトラストは技術的に難しいですし工数もかなりかかるので、「マイクロサービスだからゼロトラストにするべき」という考えは“ベスト“であって、安直に“マスト“と捉えるべきではないかなとも思っています。

スタートアップの規模感や優先度によっては、良い選択肢ではない場合の方が多いかもしれません。ですが、Gaudiy では事業拡大を見据えて

  • メガベンチャークラスになると、誰でも簡単にアクセスできないような考慮が必要になってくる(社内のコンプライアンスの観点)
  • 工数がまだ低い段階で投資した方が、のちの開発コスト削減につながる

と考えたことから、今のフェーズでゼロトラストの思想を取り入れることにしました。

最後に、ほんの一部かつごく一般的な事例になりますが、具体的に取り組んでいる対策を紹介できればと思います。

4. Gaudiyにおけるゼロトラストの適用

私たちはバックエンドサービスの実行環境に、主にCloud Runを使用しています。このCloud Run自体がゼロトラストととても親和性が高く、フルマネージドで簡単に導入できる部分があります。

そのひとつがサービス間の認証です。呼び出される側のサービスが、どのサービスからであればアクセスできるかの権限を指定することができます。

これはBeyondProdを参考にすると、セキュリティ原則のひとつである、サービス間の相互信頼を確認できる機能だと認識することができます。

このサービス間の認証は、Cloud Runを利用している人にとっては基本的なことだとは思います。ですが、BeyondProdの視点があるだけで、クラウドネイティブアーキテクチャを設計するときにセキュリティ面の対策を意識的に考えられるし、サービス間のあるべき関係性もより深く考えられるかなと思います。

加えて、Cloud Runの権限設定周りもIaCを活用して管理しています。単にクラウド設定の自動化により、デリバリーの認知負荷を低減するという意図もありますが、サービス間のコンテキスト依存の関係もコードとして理解できる点が、チーム開発や新規のアーキテクチャを構成する際に有用だなと感じています。

5. さいごに

完璧なゼロトラストを実現するには、まだまだ足りない部分があり、正直かなり難しい分野だと思います。

Gaudiyでは今後の事業成長やチーム拡大を見据えてゼロトラストを選択しましたが、事業のフェーズや規模によっては、ゼロトラストの適用は逆にコストになり、大きなリターンは生まれないとも感じました。

プロダクトの機能をつくっていくフェーズにおいては、どうしてもセキュリティに取り組む優先度が下がってしまう傾向もあると思いますが、もし事業拡大・人数の増加が見込まれるのであれば、早期に取り組んでおいて損はないと感じました。あとから適用するのは、やはりそれなりのコストがかかってきます。

またクラウドを利用する場合、クラウドが提供する各種サービスの様々な設定をきちんと理解・把握して、ビジネスに反映させていくことが改めて大切だと実感しています。

Gaudiyでもまだ試行錯誤しながら取り組んでいる段階なので、ゼロトラストやマイクロサービスアーキテクチャの設計に興味や知見がある人がいたら、ぜひお話ししたいです!

meety.net

Gaudiyの技術選定とその思想は、以下の記事をご参考ください!

techblog.gaudiy.com