SalesforceのApexでデータアクセスのセキュリティを考慮するとき、以下の4つの機能を理解することが重要です。
- アクセスレベルパラメータ(Access Level Parameters)
- WITH SECURITY_ENFORCED
- Security.stripInaccessible()
- Apex Describe Information
それぞれの役割や違い、実装例を整理しました。
1. アクセスレベルパラメータ(Access Level Parameters)
概要
- SOQLクエリやDML操作でオブジェクトやフィールドレベルのアクセス制御を行うためのパラメータ。
- Apexコードが「ユーザーの権限を考慮するか」を決めるのに使う。
- 主にDML操作(insert, update, delete)で使われる。
使えるアクセスレベル
レベル | 説明 |
---|---|
USER_MODE | ユーザーの権限を考慮する(プロファイルや権限セットを適用) |
SYSTEM_MODE | 管理者権限で実行(アクセス制限を無視) |
実装例
// USER_MODEを使用(ユーザーのアクセス権を考慮)
Database.SaveResult result = Database.insert(myRecord, AccessLevel.USER_MODE);
// SYSTEM_MODEを使用(管理者権限で実行)
Database.SaveResult result2 = Database.insert(myRecord, AccessLevel.SYSTEM_MODE);
どんなときに使う?
✅ 管理者のように実行する場合(SYSTEM_MODE)
✅ 標準のアクセス制御を適用したい場合(USER_MODE)
⚠️ 注意点
-
DML
操作で使うものなので、SOQLクエリには影響しない。 -
USER_MODE
にすると、ユーザーがアクセスできないオブジェクトやフィールドには書き込めない。
2. WITH SECURITY_ENFORCED
概要
- SOQLクエリ実行時に、ユーザーがアクセスできないフィールドを自動的に除外する。
- SOQLのクエリに直接組み込めるので簡単に使える。
- フィールドレベルセキュリティ(FLS)を考慮する。
実装例
List<Account> accounts = [SELECT Id, Name, Industry FROM Account WITH SECURITY_ENFORCED];
→ ユーザーが「Industry」フィールドにアクセス権を持っていない場合、クエリは失敗(例外発生)する。
どんなときに使う?
✅ SOQLクエリ時に、アクセス権を考慮したいとき
✅ シンプルなコードでセキュリティを担保したいとき
⚠️ 注意点
- アクセスできないフィールドが含まれていると 例外(Exception)が発生する。
- 一部のフィールドだけ取得したいときは Security.stripInaccessible() の方が便利。
3. Security.stripInaccessible()
概要
- アクセスできないフィールドを自動的に除外してくれる(クエリもDML操作も対象)。
- WITH SECURITY_ENFORCED との違い → クエリが失敗せず、アクセス可能なデータのみ取得できる。
- データの作成・更新時にも使えるので、汎用性が高い。
実装例
// クエリ実行(ユーザーがアクセスできないフィールドを自動的に除外)
SObjectAccessDecision decision = Security.stripInaccessible(AccessType.READABLE, [SELECT Id, Name, Industry FROM Account]);
List<Account> safeAccounts = (List<Account>)decision.getRecords();
→ アクセス権のない「Industry」フィールドが自動的に除外されるため、例外は発生しない。
データ更新時の使用例
Account acc = new Account(Id = '001xxxxxxx', Industry = 'Technology'); // Industryが制限されている可能性あり
SObject sanitizedAccount = Security.stripInaccessible(AccessType.UPDATABLE, acc);
update sanitizedAccount;
→ Industry フィールドが更新不可なら、自動的に除外されて安全にupdateできる。
どんなときに使う?
✅ クエリ時にアクセスできないフィールドを自動的に取り除きたいとき
✅ DML操作時に、アクセスできないフィールドを除外してエラーを防ぎたいとき
⚠️ 注意点
-
WITH SECURITY_ENFORCED
とは違い、クエリの失敗はしないが、アクセスできないフィールドは結果から消える。 - クエリだけでなく、DML操作でも使えるのがメリット。
4. Apex Describe Information
概要
- オブジェクトやフィールドのメタデータを動的に取得できる。
- フィールドレベルセキュリティ(FLS)やオブジェクトレベルセキュリティ(CRUD)のチェックをカスタム処理で行うときに使う。
- 「ユーザーがこのフィールドを読めるか・書けるか?」を事前にチェックできる。
実装例
// ユーザーが Account オブジェクトに対する read 権限を持っているか確認
if (Schema.sObjectType.Account.isAccessible()) {
List<Account> accounts = [SELECT Id, Name FROM Account];
}
// ユーザーが Account の Industry フィールドを編集できるか確認
if (Schema.sObjectType.Account.fields.Industry.isUpdateable()) {
Account acc = new Account(Id = '001xxxxxxx', Industry = 'Technology');
update acc;
}
どんなときに使う?
✅ カスタムのロジックでアクセス制御をしたいとき
✅ CRUDやFLSチェックをコードで実装したいとき
⚠️ 注意点
-
WITH SECURITY_ENFORCED
やSecurity.stripInaccessible()
の方が簡単なので、通常はそれを使う。 - 動的な権限チェックが必要な場合にのみ使う(例:カスタムUIでボタンを表示/非表示)。
まとめ:どれを使えばいい?
機能 | 役割 | 使う場面 | クエリ | DML |
---|---|---|---|---|
Access Level Parameters | DML時の権限制御 | DML(insert, update, delete)でユーザー権限を適用 | ❌ | ✅ |
WITH SECURITY_ENFORCED | クエリのセキュリティ適用 | SOQLでFLSを適用し、アクセスできない場合はエラーにする | ✅ | ❌ |
Security.stripInaccessible() | クエリとDMLのフィールド制御 | クエリ時にアクセスできないフィールドを除外 / DML時に変更不可のフィールドを削除 | ✅ | ✅ |
Apex Describe Information | 権限チェック(CRUD/FLS) | コード内で動的に権限チェックをする | ✅ | ✅ |
どれを使うべき?
-
SOQLクエリ →
WITH SECURITY_ENFORCED
orSecurity.stripInaccessible()
-
DML操作 →
Security.stripInaccessible()
orAccess Level Parameters (USER_MODE)
-
動的に権限をチェックしたい →
Apex Describe Information
適切に使い分けることで、安全でエラーの少ないApexコードを実装できます! 🚀