Gluegent Blog

Gluegent Blog

「共有設定が上手くいかない!」-- Google Drive権限の仕様解説

  • グルージェントフロー
  • 技術
「共有設定が上手くいかない!」-- Google Drive権限の仕様解説
 目次

こんにちは!エンジニアの和田です。

Google Drive と連携する機能を作っていると、「ファイルの共有設定がなぜか思った通りにならない」という場面に遭遇することがあります。
また、グルージェントフローを使っているときに、「GWS連携機能である自動処理が期待通りに動かない」という問い合わせもあります。

実はこれ、Google Drive のファイル権限(Permission)の仕様を正しく理解していないことが原因であるケースが少なくありません。

この記事では、Drive API を使う上で押さえておきたい権限の基礎知識を整理し、実際にAPIを叩きながらその挙動を確認していきます。
さらに、こうした権限の仕様が実際のプロダクト開発でどのように関わってくるのか、グルージェントフローの機能である「自動処理」もあわせてご紹介します。

Drive API をこれから触る方や、Google Workspace との連携機能を検討されている方のお役に立てれば幸いです。

Google Drive のファイル権限(Permission)の基礎

Permission リソースの基本

Google Drive におけるファイルの権限は、「role(オーナー・編集者・閲覧者など)」と「type(ユーザー・グループ・ドメイン・全員など)」の組み合わせによって表現されます。まずはこの基本構造を押さえておきましょう。

継承された権限と直接設定された権限

Google Drive のファイルには、フォルダや共有ドライブから引き継がれる権限と、ファイル単体に直接付与された権限が混在することがあります。

この混在している状況について、以下のように公式ドキュメントで詳しくまとめられているので、一緒に見ていきましょう。

  • すべての子ファイル・子フォルダは、親フォルダの権限を自動的に継承する

  • 子アイテム側で、継承した権限を削除・縮小することはできない。変更したい場合は、継承元の親フォルダ自体を変更するか、フォルダの「アクセス制限の設定」機能を使う必要がある

  • 一方で、子アイテム側により強い(制限の緩い)ロールを追加で付与することは可能。たとえばフォルダが reader 権限でも、特定のファイルだけに writer 権限を追加で与えることができる

  • アイテムを別の親フォルダへ移動すると、移動先の親フォルダの権限が再評価され、そのアイテム(およびさらにその子アイテム)に適用される

この「継承された権限は子アイテム単体では外せない」という制約は、後半で紹介するドライブ共有設定自動処理を設計・運用する上で重要なポイントになります。

GoogleDrive_権限イラスト.png

この「継承」の仕組みは、マイドライブと共有ドライブとで見え方や挙動が異なる点にも注意が必要です。

強い権限から弱い権限への変更はできない

すでに編集者(Writer)権限を持っているユーザーに対して、後から閲覧者(Reader)権限を付与しようとしても、より強い権限が優先されるため、権限が弱くなることはありません。

権限を弱めたい場合は、一度既存の権限を削除してから設定し直す必要があります。これは Drive API を扱う際によく見落とされがちなポイントです。

実際に Drive API を触ってみる

files.get()でファイルのメタ情報を取得する

まずは files.get() を使って、対象ファイルの基本的なメタ情報(ID、ファイル名、MIMEタイプなど)を取得してみます。
fields パラメータを指定することで、権限情報(permissions)もあわせて取得できる点にも触れていきます。

検証するために使用しているものは、Google社が提供している「APIs Exploere」というツールです。
このツールは、コードを記述することなく Google API メソッドを試すことが出来ます。
また、各APIのメソッドとともにリファレンスが書いてあるので、リクエストやレスポンス内の各パラメータが何を示しているのか把握するのにも役に立ちます。

今回は、以下のようなユーザーが混在するファイルに対して files.get() を実行してみました(ファイルのオーナーの権限で実行しています)。

  • 親フォルダへの共有はなく、ファイルにだけ直接「編集者」を付与されたユーザー

  • 親フォルダでは「閲覧者」、ファイルには追加で「編集者」を付与されたユーザー

ユーザー名

親フォルダの権限状況

ファイルの権限状況

ユーザーA(オーナー)

writer

owner

ユーザーB

共有無し

writer

ユーザーC

reader

writer

実行結果(一部抜粋・マスク済み)は以下の通りです。

{
  "kind": "drive#file",
  "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "name": "スプレッドシート",
  "mimeType": "application/vnd.google-apps.spreadsheet",
  "parents": [
    "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
  ],
  "shared": true,
  "ownedByMe": true,
  "permissions": [
    {
      "type": "user",
      "emailAddress": "owner@sample.com",
      "role": "owner",
      "permissionDetails": [
        { "role": "writer", "inherited": true },
        { "role": "owner",  "inherited": false }
      ]
    },
    {
      "type": "user",
      "emailAddress": "editor-only-on-file@sample.com",
      "role": "writer",
      "permissionDetails": [
        { "role": "writer", "inherited": false }
      ]
    },
    {
      "type": "user",
      "emailAddress": "viewer-on-folder-editor-on-file@sample.com",
      "role": "writer",
      "permissionDetails": [
        { "role": "reader", "inherited": true },
        { "role": "writer", "inherited": false }
      ]
    }
  ]
}

このレスポンスから読み取れることをまとめます。

permissions の各要素には、トップレベルの role(最終的に有効なロール)とは別に、permissionDetails という形で「継承分」と「直接設定分」の内訳が記録されています。

  • owner@sample.com(オーナー)
    role: owner ですが、permissionDetails を見ると、親フォルダから継承した writer(inherited: true)と、ファイルに直接設定された owner(inherited: false)の2つが同居しています。最終的に有効になるのはより強い方の owner です。最上位のロールであっても、内部的には継承分と直接設定分が別々に記録されていることが分かります。

  • editor-only-on-file@sample.com
    permissionDetails に inherited: true の項目が一切なく、writer(inherited: false)のみが存在します。親フォルダ側の共有設定とは無関係に、このファイルにだけ直接editor(編集者)権限が付与されたケースです。

  • viewer-on-folder-editor-on-file@sample.com
    親フォルダから reader(inherited: true)を継承しつつ、ファイル自体にも直接 writer(inherited: false)が追加付与されています。先ほど説明した「子アイテム側により強いロールを追加付与できる」というルールの実例で、結果としてこのユーザーの実効的な権限は writer になります。

権限に関するAPIを触ってみる

続いて permissions.list を使い、対象ファイルに設定されている権限の一覧を取得します。roleとtypeが、実際のレスポンス上でどのように表現されているかを確認します。

ここでは、親フォルダ経由で「編集者」権限を持っているユーザーDさんに注目してみます。

ユーザー名

親フォルダの権限状況

ファイルの権限状況

ユーザーD

writer

-(直接設定無し)

Before: permissions.list の結果(マスク済み)

{
  "id": "XXXXXXXXXXXXXXXXXXXX",
  "displayName": "ユーザーD",
  "type": "user",
  "emailAddress": "folder-editor-only@sample.com",
  "role": "writer",
  "permissionDetails": [
    {
      "permissionType": "file",
      "role": "writer",
      "inherited": true
    }
  ]
}

ユーザーDさんは、ファイル単体には何も設定されておらず、親フォルダから writer(inherited: true)を継承しているだけの状態です。

このユーザーDさんに対して、「このファイルだけ閲覧専用にしたい」と考え、permissions.create でreader権限を新規作成してみます。

Action: permissions.createのリクエスト

{
  "type": "user",
  "role": "reader",
  "emailAddress": "folder-editor-only@sample.com"
}

Result: permissions.createのレスポンス(マスク済み)

{
  "kind": "drive#permission",
  "id": "XXXXXXXXXXXXXXXXXXXX",
  "type": "user",
  "emailAddress": "folder-editor-only@sample.com",
  "role": "writer",
  "permissionDetails": [
    {
      "permissionType": "file",
      "role": "writer",
      "inherited": true
    }
  ]
}

リクエストでは role: "reader" を指定しましたが、返ってきたレスポンスは role: "writer" のままで、permissionDetails にも新しい reader のエントリーは追加されていません。

これは「強い権限から弱い権限への変更はできない」というルールそのものです。APIはエラーを返さずに成功レスポンスを返しますが、実際には既存の(より強い)権限がそのまま維持される、という挙動を実際に確認できました。

グルージェントフローにおける Drive API 活用 : 3つの自動処理

先ほどまで見てきた権限の仕様は、グルージェントフローの自動処理を設計する上でも重要な意味を持ちます。
ここからは、グルージェントフローが提供している「Drive API を活用した3つの自動処理」についてこれまでの内容を踏まえつつ簡単に解説をしていきます。

ここで紹介する3つの自動処理には、1つ共通する内部的な仕組みがあります。
それは、

「ファイルのオーナー本人の代理として、Google Drive API を呼び出している」

という点です。

今回、詳細は省きますが、グルージェントフローは Google Workspace の仕組みを利用してアカウントに成りすますことでAPIを実行します。
これにより、オーナー本人がその場で操作していなくても、オーナー権限が必要な処理(共有設定の変更やファイル移動など)をワークフローの自動処理として実行できるようになっています。

裏を返せば、「誰になりすましてAPIを呼ぶか」という設計そのものが、権限の仕様(継承のルールや、権限の強弱の扱い)とどう付き合うかに直結してきます。

この点を踏まえた上で、3つの自動処理を見ていきましょう。

ドライブファイルの移動自動処理

まず初めに、ドライブファイルの移動自動処理です。
この自動処理は、ファイルを決められたフォルダに移動する機能です。

ドライブファイルの移動自動処理_設定項目.png

移動の実体は「親フォルダの付け替え」であり、権限そのものを操作するわけではありません。

  • 誰の権限で :ファイルのオーナーの権限で

  • どこに :自動処理に設定されているフォルダに

  • 何をする :ファイルを移動する

 

この自動処理が成功するために重要なのは、ファイルのオーナーが移動先のフォルダに対して「編集者以上の権限があること」になります。

閲覧者の権限しか無い場合、そのフォルダにファイルやフォルダを新規作成できないことと同様に、移動することもできません。

 

また、前述のとおり、アイテムを新しい親フォルダへ移動すると移動先フォルダの権限が再評価されて適用されるため、移動先フォルダに設定されている権限がそのまま反映される点に注意が必要です。

自動処理 ドライブファイルの移動

ドライブ共有設定自動処理

続いて、ドライブ共有設定自動処理についてです。
この自動処理は、オーナー・編集者・閲覧者といった共有設定を、ワークフローの進行に応じて自動的に変更する機能です。

ドライブ共有設定自動処理_設定項目.png

「継承された権限は単体では外せない」「強い権限を弱くすることはできない」という制約は、この機能を設計・利用する上でも意識しておく必要があるポイントです。

自動処理 ドライブ共有設定

ドライブファイルのコピー自動処理

最後にドライブファイルのコピー自動処理です。
これはファイルを複製し、ワークフロー上で新しいファイルとして扱えるようにする機能です。

ドライブファイルのコピー自動処理_設定項目.png

コピーされたファイルは新規ファイルとして扱われるため、元ファイルに直接設定されている共有設定は引き継がれません。
コピーされたファイルはコピー元ファイルと同じフォルダに作成されるため、親フォルダから継承される権限については引き継がれます。

自動処理 ドライブファイルのコピー

まとめ

Drive API を扱う上では、「その権限がどこから来ているのか」「権限の強弱を変更するにはルールがある」という2点を意識しておくことが大切です。

皆様も、Drive API を使う際に意識してみてはいかがでしょうか?
また、グルージェントフローをご利用中の方は、メンテナンスにご活用いただければ幸いです。

おまけ

Google Drive 上で継承している権限を操作してみる

Google Driveの画面で「親フォルダから継承している権限を削除」しようとすると、以下のようにダイアログが出るようになっています。

親フォルダから権限削除.png

また、「親フォルダから継承している編集権限から閲覧権限にダウングレード」する際にも出ます。
この場合は、親フォルダのロールごと更新することになる点には注意です。

親フォルダの権限更新.png

共有ドライブについて

今回扱っていませんが、共有ドライブでも同じことが言えますが、コンテンツ管理者や投稿者など、マイドライブでは出てこないロール名が出てきます。

それに加えて、共有ドライブにはオーナーという概念がありません。
「グルージェントフローはオーナー本人の代理で Google Drive API を呼び出している話はどうなるの?」という部分についてはグルージェントフローのマニュアルをご確認ください。

共有ドライブ設定の注意事項