IAMの概要
認証(AuthN)と認可(AuthZ)でリソース1に対するアクセス制御を行う。
認証:どのユーザか?(誰か?)
認可:何が許可されているか?(何ができるか?)
リソースの識別
リソースに対するアクセス制御を行うためにはリソースを識別しないといけない。
OracleではすべてのリソースにはOCIDが割り当てられている。これによりリソースを識別することができる。
OCIDは形式が決められている。構文は以下の通り
ocid1.<RESOURCE TYPE>.<REALM>.[REGION].<UNIQUE ID>
各要素について
- ocid1
OCIDのバージョンを示すリテラル文字列。(基本ocid1な気がする?) -
resource type
リソースのタイプ(例: tenancy、instance、volume、vcn、subnet、user、groupなど)を指定する。
ここを見れば何のリソースなのか判別できる。(重要なのはここだけ) - realm
リソースが存在するレルム。レルムはリージョンの論理的な集合体のこと。
商用レルムを表すoc1、Government Cloud(政府の情報システム用クラウドサービス)レルムを表すoc2、Federal Government Cloud(こちらも政府向け?調べてもよくわからなかった)レルムを表すoc3がある。
(日本政府向けでもOracleが一部使われるようになったらしい) - region
リソースが存在するリージョン(たとえば、phx、iad、eu-frankfurt-1など)。 - unique ID
IDの一意の部分。自動的にランダムなIDが割り振られる。
OCIではリソースをOCIDで識別する。
OCIDのresource typeを見るとそのリソースが何のリソースなのかわかる。
AuthN(認証)
認証は各プリンシパルをグループ化し、グループに対して認証を行う。
ユーザ等の認証に用いられる情報をクレデンシャルという。
(IAM認証でいうユーザー名とパスワードなど)
プリンシパルについて
ユーザーやリソースにアクセスするインスタンスなどの**認証対象** プリンシパルには以下の3種類がある。 - ユーザー 個人やアプリケーション自体。 グループで管理。(複数のグループに所属することも可能) - リソース(インスタンス)プリンシパル OCIのリソースやOCIサービスに対してAPIコールを行うインスタンスなど。 動的グループで管理。 https://speakerdeck.com/ocise/ociji-shu-zi-liao-idoyobiakusesuguan-li-iam-xiang-xi?slide=10 - サービスプリンシパル OCIサービスをまとめたもの。あらかじめ登録されており、ユーザーによる追加はできない。認証方法には以下の3つがある。
- IAM認証
ユーザー名とパスワードで認証を行う。
ユーザー名が必要なためユーザー(人間)に対してのみ。
パスワードのリセットやマルチファクタ認証などもWEBコンソール上で行える。 - API署名キー
インスタンスなどはIAM認証ができないのでこれを用いる。
公開キーを登録し秘密鍵で認証。 - 認証トークン
API署名キーがサポートされていない場合(Google、Xなどが提供するサードパーティーAPI向け)
各ユーザーが同時に最大2つの認証トークンを持つことが可能。
プリンシパルをグループ化してグループに対してリソースへの認証を行う。
認証方法はIAM認証、API署名キー、認証トークンの3つがある。
認証時に用いる情報をクレデンシャルと呼ぶ。
アイデンティティ・ドメイン
認証ではプリンシパルをグループ化する必要があるが、認証するユーザーやグループなどの管理を行うにはアイデンティティ・ドメインと呼ばれる概念が存在する。
ユーザー、グループ、動的グループなどを束ね管理するためのものなので、ポリシーやコンパートメント、ネットワークソースなどは含まれない。(認証なのでリソース側ではない)
アイデンティティ・ドメイン補足
従来はIAM(OCI特化の認証基盤)とIDCS(他のOracleサービス用認証基盤)という2つの認証基盤が存在しており、これらを1つに統合した認証基盤(認証機能)がアイデンティティ・ドメイン。認証するユーザーやグループなどの管理を行う概念。
ユーザー、グループ、動的グループなど認証対象を束ね管理するためのもの。
動的グループ(Dynamic Group)
インスタンスなど(ユーザ以外)をグループ化したもの。
マッチングルールがあり、それに当てはまるものは自動的にグループに入る。
例:インスタンスのコンパートメントIDに'ocid'とついていたら
Any {instance.compartment.id = 'ocid'}
ユーザ以外のプリンシパルをグループ化したもの。
マッチングルールを設定し、当てはまった場合自動的に動的グループに入る。
AuthZ(認可)
グループ、動的グループに対してアクセス許可を与える。(認可されているリソースにアクセスできる)
-
最小権限の原則という概念
デフォルトでは何の操作も許可されていない。
ポリシーでリソースに対するアクセス(できること)を許可していくイメージ。
ポリシーの書き方
認可の内容を制御するための設定を記述する。
構文は以下の通り
Allow <subject> to <verb> <resource-type> in <location> where <conditions>
Subject(誰が) to verb(何を)resorce-type(何に対して) in location(どのコンパートメントの) where conditions(どういった条件のとき)
https://docs.oracle.com/ja-jp/iaas/Content/Identity/Concepts/policysyntax.htm
-
Subject句(誰が)
グループ名(OCIサービスの場合はサービス名)と名前又はOCIDでグループ・サービスを指定する。
複数のグループ名またはグループ名の場合は、カンマで区切って指定する。
例:group a, b
any-user
ですべてのユーザーにも適用可能。
構文
- グループ
group <group_name>
group id <group_ocid>
- 動的グループ
dynamic-group <dynamic-group_name>
dynamic-group id<dynamic-group_ocid>
- すべてのユーザー
any-user
どのグループに対して認証を行うか指定する。
構文:グループの種類<グループ名 or OCID>
-
Action句(どのリソースの何を許可する)
ポリシーのverb
からresorce-type
までの部分
verb(動詞、何を許可するか)
全部で4種類。上に行くほど権限が強くなる。- manage(管理する)
リソースのすべての権限。(リソースの作成・削除など) - use(使う)
リソースの変更。 - read(読み取る)
上記に加えメタデータも読み取り可能。 - inspect(検査する)
メタデータ(機密情報など)以外を読み取り可能。外部監査向け
resorce-type(何に対して)
リソースタイプを指定する。以下の3種類。
- 個々のリソース・タイプ(vcns、subnets、instances、volumesなど)。
- ファミリ・リソース・タイプ(virtual-network-family、instance-family、volume-familyなどリソースの種類の集合体)。
- all-resources:コンパートメント(またはテナンシ)内のすべてのリソースを対象
以下のスライドがわかりやすい。
https://speakerdeck.com/ocise/ociji-shu-zi-liao-idoyobiakusesuguan-li-iam-gai-yao?slide=13
どのリソースの何を許可するかを表す。
何を(verb): manage, use, read, inspect
リソース(resorce-type):個々のリソース・タイプ, ファミリ・リソース・タイプ, all-resources
Permissions(権限)について
AuthZの原子単位。これを用いるとverbごとにさらに細かく設定が可能。
ポリシーでは動詞とリソースタイプを指定するが、それらを指定した際にPermission(とAPI操作)が付与されるイメージ。
verb+resorce type | Manage Volumes | Use Volumes | Read Volumes | Inspect Volumes |
---|---|---|---|---|
Permission | VOLUME_INSPECT VOLUME_UPDATE VOLUME_WRITE VOLUME_CREATE VOLUME_DELETE VOLUME_MOVE | VOLUME_INSPECT VOLUME_UPDATE VOLUME_WRITE | VOLUME_INSPECT | VOLUME_INSPECT |
API | CreateVolume DeleteVolume ChangeVolumeCompartment | AttachVolume DetachVolume | No extra | ListVolume GetVolume |
例:ボリュームに対するポリシー
ここでmanageの権限は与えたいが、delete(削除)の権限は与えたくないといった場合、where句でPermissionを制御する。
パターン1:delete以外の権限を与える。
Allow group XYZ to manage groups in tenancy where any { request.permission=‘VOLUME_INSPECT’, request.permission=‘VOLUME_CREATE’, request.permission=‘VOLUME_WRITE’, request.permission=‘VOLUME_UPDATE’, request.permission=‘VOLUME_MOVE’ }
パターン2:deleteのみ権限を付与しない。
Allow group XYZ to manage groups in tenancy where request.permission != ‘VOLUME_DELETE’
※request.permission:リクエストを送った側のpermissionに
verbはPermissionsという細かい権限の集合であり、Where句で権限を与えることができる。
request.permissionでリクエストを送った側のpermissionに権限を付与できる。
-
in句(location)
名前またはOCIDで単一のコンパートメントまたはコンパートメント・パスを指定する。
複数のコンパートメントを指定するには、別のポリシーを作成する必要あり。
テナンシ(アカウントに割り当てられた領域。テナンシを分割したものがコンパートメント)
構文
tenancy
compartment <compartment_name>
compartment id <compartment_ocid>
どのコンパートメントか(テナンシで指定も可能)を表す。
コンパートメント名かそのパス、またはtenancyで指定する。
- Where句(conditions)
○○から始まるリソースなど、条件を設定する。
構文
- 単一条件の場合
比較したい値 = 値
比較したい値 != 値
- 複数条件の場合
or条件
any{比較したい値 = 値}
and条件
all{比較したい値 = 値}
比較する値の書き方
- 文字列
'johnsmith@example.com'
- パターン
「*」はワイルドカードとして扱う。
/HR*/ (「HR」で始まる文字列と一致します)
/*HR/ (「HR」で終わる文字列と一致します)
/*HR*/ (「HR」を含む文字列と一致します)
条件を指定する。
or条件はany and条件はallで指定する。
文字列の指定も可能。パターン検索の場合はスラッシュで文字列を囲い、「*」はワイルドカードとして扱う。
コンパートメント
概要
ポリシーで認可するリソースのコンパートメントを指定していたが、このコンパートメントとは リソースを束ねる概念 のことである。
リソースは1つのコンパートメントに属す。(複数のコンパートメントに属すことはできない)
コンパートメントの特徴
-
入れ子構造
最初に作られるテナンシ(ルート・コンパートメント)の中に入れ子することができる(テナンシを含まず6個)
上位のコンパートメントに適用されるポリシーは下位のコンパートメントにも適用される。(コンパートメントは親コンパートメントからポリシーを継承する。最低限のポリシーを適用することが必要。)
-
複数のリージョンにまたがれる(グローバルである)
他のリージョンにあるリソースも束ねられる。 -
コンパートメントごとにリソースの使用量や予算を設定することもできる
ポリシーのアタッチ
コンパートメントに対してポリシーをアタッチすることができる(ポリシーを適用するにはコンパートメントにアタッチする必要がある。)
上位のコンパートメントにあるポリシーはそのコンパートメントでポリシーを管理する権限がないユーザでは編集・削除はできない。
リソースの移動
リソースは1つのコンパートメントにしか属せないが、別のコンパートメントに移動することができる。
コンパートメントエクスプローラー
コンパートメント内のリソースを一覧で表示できる。 全てのリージョンのリソースが閲覧可能。- コンパートメントはリソースを束ねる概念。
- リソースはいずれか1つのコンパートメントに属する。複数のコンパートメントには属すことができないが、別のコンパートメントに移動することはできる。
- ポリシーはコンパートメントごとに適用する。
- コンパートメントは入れ子構造にすることができ、上位のコンパートメントにアタッチされたポリシーは下位のコンパートメントにも適用される。
- コンパートメントはグローバルなリソースである。(他リージョンのリソースも束ねられる)
ネットワークソース
ポリシーではアクセスできるIPアドレスの範囲を指定することもできる。
IPアドレスの範囲を指定しネットワークソースに定義し、ポリシーのwhere句でアクセスを制御する。
例:corpnetという名前で定義したIPアドレス範囲からのアクセス(リクエスト)で○○というグループに属している場合、テナンシの××にmanageの権限を与える。
allow group ○○ to manage ×× in tenancy where request.networkSource.name='corpnet'
ネットワークソースを利用することでIP制限をかけることができる。
request.networkSource.nameでネットワークソースの名前を指定できる。
タグに基づくアクセス制御
リソースにタグをつけ、そのタグを元にアクセスを制御する。
タグは以下の3つの要素から成り立つ。
- タグ・ネームスペース:タグ・キーのコンテナ(集合)
- キー:タグを参照するためのもの
- タグ値:キーに与えたvalue
リクエスト側リソースに適用されるタグ(グループ、動的グループ、コンパートメント)
request.principal.○○.tagの形で記載。
グループ
request.principal.group.tag.{tagNamespace}.{tagKeyDefinition}= ''
例:
subject:すべてのユーザー
resorce-type:コンパートメント"HR"のインスタンスに対して
verb:manageの権限を与える。
conditions:グループタグに"Prod"というタグが付いていること。
allow any-user to manage instances in compartment HR where request.principal.group.tag.Operations.Project= 'Prod'
アクセスをリクエストする(インスタンスの)動的グループ
request.principal.group.tag.{tagNamespace}.{tagKeyDefinition}= '<value>'
例:コンパートメント"HR"のインスタンスに対してmanageの権限を与える。条件として、"InstancesA"という動的グループに含まれており、グループタグに"Prod"というタグが付いていること。
allow dynamic-group InstancesA to manage instances in compartment HR where request.principal.group.tag.Operations.Project= 'Prod'
動的グループ内のリソースが常駐するコンパートメント
`request.principal.compartment.tag.{tagNamespace}.{tagKeyDefinition}= '<value>'`
例:動的グループInstancesAのメンバーであり、Operations.Project='Prod'でタグ付けされたコンパートメント内にも常駐するインスタンスは、テナンシ内のインスタンスを管理できる。
allow dynamic-group InstancesA to manage instances in tenancy where request.principal.compartment.tag.Operations.Project= 'Prod'
request.principal.○○.tag.{tagNamespace}.{tagKeyDefinition}
ターゲット・リソース(リクエスト対象)に適用されるタグ(コンパートメント、リソース)
request.resource.○○.tagの形で記載。例は省略。
- リソース
target.resource.tag.{tagNamespace}.{tagKeyDefinition}='<value>'
- コンパートメント
target.resource.compartment.tag.{tagNamespace}.{tagKeyDefinition}='<value>'
request.resource.○○.tag.{tagNamespace}.{tagKeyDefinition}
参考資料
- IAM
-
OCIで利用できるサービスや機能のこと(ストレージサービス、ネットワーキングサービスなど…) ↩