Cloud Storage의 Firebase Security Rules를 사용하여 읽기 및 쓰기 액세스 권한이 있는 사용자를 결정합니다.
Cloud Storage에 저장된 파일 및 파일의 구조
어떤 메타데이터를 포함할지
파악할 수 있습니다 Cloud Storage Security Rules는
request
및 resource
를 고려하여 원하는 작업을 허용하거나 거부합니다.
파일 업로드나 파일 메타데이터
가져오기와 같이 작동합니다 이러한 참조 문서에서 다루는
규칙 유형, request
및 resource
의 속성, 데이터
Cloud Storage Security Rules
규칙
rule
은 request
이 다음과 같은지 확인하기 위해 평가되는 표현식입니다.
작업을 수행할 수 있습니다.
유형
허용
allow
규칙은 read
또는 write
와 같은 메서드와
선택적으로 사용할 수 있습니다. 규칙이 실행되면 조건이 평가되고
조건이 true
로 평가되면 원하는 메서드가 허용됩니다. 그렇지 않으면
메서드가 거부됩니다. 조건이 없는 allow
규칙은
지정할 수 있습니다.
// Always allow method allow <method>; // Allow method if condition is true allow <method>: if <condition>;
현재 지원되는 유일한 규칙 유형은 allow
입니다.
요청 메서드
Read
read
메서드는 파일 데이터 또는 메타데이터를 읽는 모든 요청에 적용됩니다.
여기에는 파일 다운로드 및 파일 메타데이터 읽기 등이 포함됩니다.
// Always allow reads allow read; // Allow reads if condition evaluates to true allow read: if <condition>;
Write
write
메서드는 파일 데이터 또는 메타데이터가 기록되는 모든 요청에 적용됩니다.
여기에는 파일 업로드, 파일 삭제 및 파일 메타데이터 업데이트가 포함됩니다.
// Always allow writes allow write; // Allow writes if condition evaluates to true allow write: if <condition>;
일치
규칙은 사용자가 request
(예: 파일 업로드 또는 다운로드)할 때 실행됩니다.
규칙이 적용되는 파일 경로와 일치합니다. match
는 경로와 본문으로 구성됩니다.
allow
규칙을 하나 이상 포함해야 합니다. 일치하는 경로가 없으면 요청은
거부됩니다.
전체 이름이 지정된 경로를 match
하거나, 모든 항목과 일치하도록 와일드 카드를 삽입할 수 있습니다.
특정 패턴에 맞는 경로를 찾을 수 있습니다.
경로 세그먼트
single_segment
단일 경로 세그먼트를 사용하여 저장된 파일과 일치하는 규칙을 만들 수 있습니다. Cloud Storage.
// Allow read at "path" if condition evaluates to true match /path { allow read: if <condition>; }
여러 경로 세그먼트 및 중첩 경로도 허용됩니다.
// Allow read at "path/to/object" if condition evaluates to true match /path { match /to { match /object { allow read: if <condition>; } } }
{single_segment_wildcard}
동일한 경로에 있는 여러 파일에 규칙을 적용하려면
특정 경로에 있는 모든 파일을 일치시키기 위한 와일드 카드 경로 세그먼트입니다. 와일드 카드 변수
변수를 중괄호로 묶어 경로에 선언됩니다({variable}
).
이 변수는 match 문 내에서 string
로 액세스할 수 있습니다.
// Allow read at any path "/*", if condition evaluates to true match /{single_path} { // Matches "path", "to", or "object" but not "path/to/object" allow read: if <condition>; }
여러 경로 세그먼트와 중첩된 경로에도 와일드 카드가 포함될 수 있습니다.
// Allow read at any path "/path/*/newPath/*", if condition evaluates to true match /path/{first_wildcard} { match /newPath/{second_wildcard} { // Matches "path/to/newPath/newObject" or "path/from/newPath/oldObject" allow read: if <condition>; } }
{multi_segment_wildcard=**}
특정 경로 또는 경로 아래에 있는 원하는 수만큼의 경로 세그먼트를 일치시키려면 다음을 사용하세요. 다중 세그먼트 와일드 카드로, 볼 수 있습니다 사용자에게 자신만의 자유 양식을 제공할 때 유용할 수 있습니다. 저장 공간을 확보하거나, 다양한 경로 세그먼트 (예: 공개적으로 읽을 수 있는 파일 집합을 만들거나 모든 쓰기)
다중 세그먼트 와일드 카드 경로가 단일 세그먼트와 유사하게 선언됨
와일드 카드, 변수 끝에 =**
추가:
{variable=**}
일치 항목 내에서 다중 세그먼트 와일드 카드 변수를 사용할 수 있습니다.
문을 path
객체로 반환합니다.
// Allow read at any path "/**", if condition evaluates to true match /{multi_path=**} { // Matches anything at or below this, from "path", "path/to", "path/to/object", ... allow read: if <condition>; }
요청
request
변수는
모든 요청이 수행되도록 할 수 있습니다. request
변수에는
속성: 수신되는 요청을 허용할지 여부를 결정하는 데 사용할 수 있습니다.
속성
auth
인증된 사용자가 Cloud Storage에 대해 요청을 수행하면
auth
변수는 사용자의 uid
(request.auth.uid
)로 채워집니다.
Firebase Authentication JWT (request.auth.token
)의 클레임도 포함됩니다.
request.auth.token
에는 다음 키 중 일부 또는 전부가 포함됩니다.
필드 | 설명 |
---|---|
email |
계정과 연결된 이메일 주소(있는 경우)입니다. |
email_verified |
true 는 사용자가 email 주소에 대한 액세스 권한이 있는지 확인한 경우입니다. 일부 제공업체는 자동으로 자체 이메일 주소를 확인합니다. |
phone_number |
계정과 연결된 전화번호(있는 경우)입니다. |
name |
사용자의 표시 이름(설정된 경우)입니다. |
sub |
사용자의 Firebase UID입니다. 프로젝트 내에서 고유합니다. |
firebase.identities |
사용자 계정과 연결된 모든 ID의 사전입니다. 사전의 키는 email , phone , google.com , facebook.com , github.com , twitter.com 일 수 있습니다. 사전의 값은 계정과 연결된 각 ID 공급업체의 고유한 식별자 배열입니다. 예를 들어 auth.token.firebase.identities["google.com"][0] 에는 계정과 연결된 첫 번째 Google 사용자 ID가 포함됩니다. |
firebase.sign_in_provider |
토큰을 얻기 위해 사용된 로그인 제공업체입니다. 문자열 custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com 중 하나일 수 있습니다. |
firebase.tenant |
계정과 연결된 tenantId(있는 경우)입니다. 예: tenant2-m6tyz |
커스텀 인증을 사용하는 경우 request.auth.token
에는 모든 커스텀
소유권 주장이 있을 수 있습니다.
인증되지 않은 사용자가 요청을 수행하면 request.auth
는 null
입니다.
// Allow requests from authenticated users allow read, write: if request.auth != null;
path
path
변수에는 request
가 실행되는 경로가 포함됩니다.
있습니다.
// Allow a request if the first path segment equals "images" allow read, write: if request.path[0] == 'images';
resource
resource
변수에는 업로드 중인 파일의 메타데이터 또는
업데이트된 메타데이터입니다. 이것은
resource
변수:
새 메타데이터가 아닌 요청된 경로입니다.
// Allow a request if the new value is smaller than 5MB allow read, write: if request.resource.size < 5 * 1024 * 1024;
request.resource
에는 resource
의 다음 속성이 포함됩니다.
속성 |
---|
name |
bucket |
metadata |
size |
contentType |
time
time
변수에는 현재 서버 시간을 나타내는 타임스탬프가 포함됩니다.
즉 요청을 평가하는 데 사용됩니다 이를 사용하여 시간 기반 액세스를 제공할 수 있습니다.
예: 특정 날짜까지만 파일 업로드 허용,
또는 파일을 업로드한 후 최대 한 시간 동안만 읽을 수 있도록 허용할 수 있습니다.
// Allow a read if the file was created less than one hour ago allow read: if request.time < resource.timeCreated + duration.value(1, 'h');
리소스
resource
변수에는 다음 위치에 있는 파일의 파일 메타데이터가 포함됩니다.
Cloud Storage(예: 파일 이름, 크기, 생성 시간,
커스텀 메타데이터를 설정합니다
속성
name
파일의 경로를 포함하여 파일의 전체 이름이 포함된 문자열입니다.
// Allow reads if the resource name is "path/to/object" allow read: if resource.name == 'path/to/object'
bucket
Google Cloud Storage 버킷의 이름을 지정합니다
// Allow reads of all resources in your bucket allow read: if resource.bucket == '<your-cloud-storage-bucket>'
generation
Google Cloud Storage를 포함하는 int 객체 생성 있습니다. 객체 버전 관리에 사용됩니다.
// Allow reads if the resource matches a known object version allow read: if resource.generation == <known-generation>
metageneration
Google Cloud Storage를 포함하는 int 객체 메타세대 있습니다. 객체 버전 관리에 사용됩니다.
// Allow reads if the resource matches a known object metadata version allow read: if resource.metageneration == <known-generation>
size
바이트 단위의 파일 크기를 포함하는 정수입니다.
// Allow reads if the resource is less than 10 MB allow read: if resource.size < 10 * 1024 * 1024;
timeCreated
파일이 생성된 시간을 나타내는 타임스탬프입니다.
// Allow reads if the resource was created less than an hour ago allow read: if resource.timeCreated < request.time + duration.value(60, "m")
updated
파일이 최종 업데이트된 시간을 나타내는 타임스탬프입니다.
// Allow reads if the resource was updated less than an hour ago allow read: if resource.updated < request.time + duration.value(60, "m")
md5Hash
MD5 해시가 포함된 파일에서 참조됩니다.
// Allow writes if the hash of the uploaded file is the same as the existing file allow write: if request.resource.md5Hash == resource.md5Hash;
crc32c
crc32c 해시를 사용하여 파일에서 참조됩니다.
// Allow writes if the hash of the uploaded file is the same as the existing file allow write: if request.resource.crc32c == resource.crc32c;
etag
etag를 포함하는 파일에서 참조됩니다.
// Allow writes if the etag matches a known object etag allow write: if resource.etag == <known-generation>
contentDisposition
파일의 콘텐츠 처리를 포함하는 문자열입니다.
// Allow reads if the content disposition matches a certain value allow read: if resource.contentDisposition == 'inlined';
contentEncoding
파일의 콘텐츠 인코딩을 포함하는 문자열입니다.
// Allow reads if the content is encoded with gzip allow read: if resource.contentEncoding == 'gzip';
contentLanguage
파일의 콘텐츠 언어를 포함하는 문자열입니다.
// Allow reads if the content language is Japanese allow read: if resource.contentLanguage == 'ja';
contentType
파일의 콘텐츠 유형이 포함된 문자열입니다.
// Allow reads if the content type is PNG. allow read: if resource.contentType == 'image/png';
metadata
추가 개발자 제공 메타데이터가 포함된 Map<String, String>
있습니다.
// Allow reads if a certain metadata field matches a desired value allow read: if resource.metadata.customProperty == 'customValue';
Firestore.get 및 Firestore.exists
firestore.get()
및 firestore.exists()
함수를 사용하면
Cloud Firestore의 문서를 사용하여 복잡한 승인 기준을 평가합니다.
firestore.get()
및 firestore.exists()
함수
문서 경로를 지정해야 합니다. 변수를 사용하여
firestore.get()
및 firestore.exists()
이면 명시적으로 이스케이프 처리해야 함
변수를 사용하여 $(variable)
구문을 사용할 수 있습니다.
Firestore.get
Cloud Firestore 문서의 콘텐츠를 가져옵니다.
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.uid)).data.memberships } } }
Firestore.exists
Cloud Firestore 문서가 있는지 확인합니다.
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.uid)) } } }
서비스
service
는 Cloud Storage Security Rules 파일의 첫 번째 선언입니다.
는 이러한 규칙이 적용될 서비스를 지정합니다.
이름
name
적용될 서비스 규칙의 이름입니다. 유일한 현재 값은
firebase.storage
// Specify the service name service firebase.storage { match /b/{bucket}/o { ... } }
데이터 유형
Rules 언어를 사용하면 is
연산자를 사용하여 유형을 확인할 수 있습니다.
// For example
a is null
a is string
null
null
데이터 유형이 존재하지 않는 값을 나타냅니다.
allow read: if request.auth != null;
bool
bool
유형은 불리언 true
또는 false
값을 나타냅니다.
allow read: if true; // always succeeds allow write: if false; // always fails
비교
==
연산자 !=
를 사용하여 불리언 값을 비교할 수 있습니다.
불리언 연산
작업 | 표현식 |
---|---|
AND |
x && y |
OR |
x || y |
NOT |
!x |
작업이 단락되며 true
, false
또는
오류.
allow read: if true || false; // always succeeds, short circuits at true allow write: if false && true; // always fails, short circuits at false
int
및 float
int
및 float
유형은 숫자를 나타냅니다. 정수는 0
, 1
, -2
등입니다.
인 반면 부동 소수점은 1.0
, -2.0
, 3.33
등입니다.
정수는 부호 있는 64비트 값이고 부동 소수점 수는 64비트 IEEE 754 호환 값입니다.
int
유형의 값은 비교에 사용될 때 float
로 강제 변환됩니다.
float
값을 가진 산술 연산.
비교
==
, !=
, >
, <
를 사용하여 정수와 부동 소수점 수를 비교하고 정렬할 수 있습니다.
>=
, <=
연산자.
산술
정수와 부동 소수점 수의 덧셈, 뺄셈, 곱셈, 나눗셈, 모듈로딩이 가능합니다. 부정:
작업 | 표현식 |
---|---|
덧셈 | x + y |
빼기 | x - y |
곱하기 | x * y |
나누기 | x / y |
나머지 | x % y |
부정 | -x |
수학 함수
Cloud Storage의 Firebase Security Rules는 여러 수학 도우미도 제공합니다. 함수를 사용하여 표현식을 단순화합니다.
함수 | 설명 |
---|---|
math.ceil(x) |
숫자 값의 상한선 |
math.floor(x) |
숫자 값의 최소값 |
math.round(x) |
입력 값을 가장 가까운 정수로 반올림합니다. |
math.abs(x) |
입력의 절댓값 |
math.isInfinite(x) |
값이 ±∞ 인지 테스트하고 bool 를 반환합니다. |
math.isNaN(x) |
값이 숫자 NaN 가 아닌지 테스트합니다. bool 을 반환합니다. |
string
비교
==
, !=
, >
, <
, >=
,
<=
연산자.
연결
문자열은 +
연산자를 사용하여 연결할 수 있습니다.
// Concatenate a file name and extension 'file' + '.txt'
색인 및 범위
index
연산자인 string[]
는 다음 문자가 포함된 문자열을 반환합니다.
를 반환합니다.
// Allow reads of files that begin with 'a' match /{fileName} { allow read: if fileName[0] == 'a'; }
range
연산자 string[i:j]
는
i
(포함)부터 j
까지 지정된 색인 사이의 문자
(제외). i
또는 j
를 지정하지 않으면 기본적으로 0으로 설정되고
각각 문자열이지만 i
또는 j
이상을 지정해야 합니다.
- 범위가 유효해야 합니다.
// Allow reads of files that begin with 'abcdef' match /{fileName} { allow read: if fileName[0:6] == 'abcdef'; }
제공된 색인이 제공된 경우 index
및 range
연산자는 오류를 생성합니다.
문자열 경계를 초과합니다.
size
문자열의 문자 수를 반환합니다.
// Allow files with names less than 10 characters match /{fileName} { allow write: if fileName.size() < 10; }
matches
정규 표현식 일치를 수행하고, 문자열이true
와 같은 정규식이 됩니다. 용도
Google RE2 구문.
// Allow writes to files which end in ".txt" match /{fileName} { allow write: if fileName.matches('.*\\.txt') }
split
제공된 정규 표현식에 따라 문자열을 분할하고 list
을 반환합니다.
학습합니다. Google RE2 구문을 사용합니다.
// Allow files named "file.*" to be uploaded match /{fileName} { allow write: if fileName.split('.*\\..*')[0] == 'file' }
path
경로는 선택사항인 패턴 일치를 사용하는 디렉터리와 유사한 이름입니다. 이
슬래시가 있는 경우 /
는 경로 세그먼트의 시작을 나타냅니다.
path
string
인수를 path
로 변환합니다.
// Allow reads on a specific file path match /{allFiles=**} { allow read: if allFiles == path('/path/to/file'); }
timestamp
타임스탬프는 UTC 기준이며 사용 가능한 값은 0001-01-01T00.00.00Z로 시작합니다. 9999-12-31T23.59.59Z로 끝납니다.
비교
타임스탬프는 ==
, !=
, >
, <
, >=
,
<=
연산자.
산술
타임스탬프는 다음과 같습니다.
표현식 | 결과 |
---|---|
timestamp + duration |
timestamp |
duration + timestamp |
timestamp |
timestamp - duration |
timestamp |
timestamp - timestamp |
duration |
duration + duration |
duration |
duration - duration |
duration |
date
year
, month
, day
만 포함된 timestamp
값
// Allow reads on the same day that the resource was created. allow read: if request.time.date() == resource.timeCreated.date()
year
1~9, 999 사이의 정수로 표시된 연도 값입니다.
// Allow reads on all requests made before 2017 allow read: if request.time.year() < 2017
month
정수(1~12)의 월 값입니다.
// Allow reads on all requests made during the month of January allow read: if request.time.month() == 1;
day
월의 현재 날짜를 정수로 표현한 값(1~31 사이의 값)입니다.
// Allow reads on all requests made during the first day of each month allow read: if request.time.day() == 1;
time
현재 시간이 포함된 duration
값입니다.
// Allow reads on all requests made before 12PM allow read: if request.time.time() < duration.time(12, 0, 0, 0);
hours
0~23 사이의 정수로 표시된 시간 값입니다.
// Allow reads on all requests made before 12PM allow read: if request.time.hours() < 12;
minutes
0~59 사이의 정수로 된 분 값입니다.
// Allow reads during even minutes of every hour allow read: if request.time.minutes() % 2 == 0;
seconds
0~59 사이의 정수로 표시된 초 값입니다.
// Allow reads during the second half of each minute allow read: if request.time.seconds() > 29;
nanos
정수로 된 소수(초)입니다(나노 단위).
// Allow reads during the first 0.1 seconds of each second allow read: if request.time.nanos() < 100000000;
dayOfWeek
요일로, 1 (월요일)에서 7 (일요일)까지입니다.
// Allow reads on weekdays (Monday to Friday) allow read: if request.time.dayOfWeek() < 6;
dayOfYear
당해 연도의 일(1~366)입니다.
// Allow reads every fourth day allow read: if request.time.dayOfYear() % 4 == 0;
toMillis
Unix 에포크 이후의 현재 시간(밀리초)을 반환합니다.
// Allow reads if the request is made before a specified time allow read: if request.time.toMillis() < <milliseconds>;
duration
지속 시간 값은 나노초입니다.
비교
==
, !=
, >
, <
, >=
,
<=
연산자.
산술
Durations(기간)는 다음과 같습니다.
표현식 | 결과 |
---|---|
timestamp + duration |
timestamp |
duration + timestamp |
timestamp |
timestamp - duration |
timestamp |
timestamp - timestamp |
duration |
duration + duration |
duration |
duration - duration |
duration |
seconds
현재 기간의 시간(초)입니다. -315,576,000,000 사이여야 합니다. +315,576,000,000(포함)입니다.
nanos
현재 기간의 소수 초 (나노초)입니다. 필수 -999,999,999~+999,999,999(포함) 0이 아닌 초 0이 아닌 나논초의 경우 두 기호는 일치해야 합니다.
duration.value
기간은 duration.value(int magnitude, string units)
를 사용하여 만들 수 있습니다.
이 함수는 주어진 규모와 단위로 기간을 생성합니다.
// All of these durations represent one hour: duration.value(1, "h") duration.value(60, "m") duration.value(3600, "s")
가능한 unit
는 다음과 같습니다.
기간 | unit |
---|---|
주 | w |
일 | d |
시간 | h |
분 | m |
초 | s |
밀리초 | ms |
나노초 | ns |
duration.time
기간은
duration.time(int hours, int minutes, int seconds, int nanoseconds)
함수,
지정된 시간, 분, 초 및
나노초입니다.
// Create a four hour, three minute, two second, one nanosecond duration duration.time(4, 3, 2, 1)
list
목록에는 값의 순서가 지정된 배열이 포함되며, null
, bool
,
int
, float
, string
, path
, list
, map
, timestamp
또는 duration
유형 list
의 x
과 y
, int
유형의 i
및 j
가 지정됨
생성
목록을 만들려면 대괄호 사이에 값을 추가합니다.
// Create a list of strings ['apples', 'grapes', 'bananas', 'cheese', 'goats']
비교
==
연산자 !=
를 사용하여 목록을 비교할 수 있습니다. 두 목록이 같음
모든 값이 같아야 합니다.
색인 및 범위
index
연산자 list[]
는
목록.
// Allow reads of all files that begin with 'a' match /{fileName} { allow read: if fileName[0] == 'a'; }
range
연산자 list[i:j]
는
지정된 색인으로, i
(포함)부터 j
(제외)까지입니다. i
또는 j
가 다음에 해당하는 경우
지정되지 않은 경우 기본값은 각각 0과 목록 크기이지만
범위가 유효하려면 i
또는 j
을(를) 지정해야 합니다.
// Allow reads of all files that begin with 'abcdef' match /{fileName} { allow read: if fileName[0:6] == 'abcdef'; }
in
목록에 원하는 값이 있으면 true
, 없으면 false
를 반환합니다.
있습니다.
// Allow read if a filename has the string 'txt' in it match /{fileName} { allow read: if 'txt' in fileName.split('\\.'); }
join
문자열 목록을 지정된 문자열로 구분된 단일 문자열로 결합합니다.
// Allow reads if the joined array is 'file.txt' allow read: if ['file', 'txt'].join('.') == 'file.txt';
size
목록에 있는 항목의 수입니다.
// Allow read if there are three items in our list allow read: if ['foo', 'bar', 'baz'].size() == 3;
hasAll
목록에 모든 값이 있으면 true
를 반환합니다.
// Allow read if one list has all items in the other list allow read: if ['file', 'txt'].hasAll(['file', 'txt']);
map
맵에는 키-값 쌍이 포함되며, 여기서 키는 문자열이며 값은 무엇이든 가능합니다.
/: null
, bool
, int
, float
, string
, path
, list
, map
,
timestamp
또는 duration
입니다.
생성
맵을 만들려면 중괄호 사이에 키-값 쌍을 추가합니다.
// Create a map of strings to strings { 'mercury': 'mars', 'rain': 'cloud', 'cats': 'dogs', }
비교
==
연산자 !=
를 사용하여 지도를 비교할 수 있습니다. 두 지도의 균등
를 사용하려면 모든 키가 맵에 있어야 하고 모든 값이 같아야 합니다.
색인
맵의 값은 대괄호 또는 점 표기법을 사용하여 액세스합니다.
// Access custom metadata properties allow read: if resource.metadata.property == 'property' allow write: if resource.metadata['otherProperty'] == 'otherProperty'
키가 없으면 error
이 반환됩니다.
in
원하는 키가 맵에 있으면 true
, 없으면 false
을 반환합니다.
있습니다.
// Allow reads if a property is present in the custom metadata allow read: if property in resource.metadata;
size
지도에 있는 키의 수입니다.
// Allow reads if there's exactly one custom metadata key allow read: if resource.metadata.size() == 1;
keys
맵의 모든 키 목록입니다.
// Allow reads if the first metadata key is 'myKey' allow read: if resource.metadata.keys()[0] == 'myKey';
values
맵의 모든 값 목록을 키 순서로 표시합니다.
// Allow reads if the first metadata value is 'myValue' allow read: if resource.metadata.values()[0] == 'myValue';
오류
오류 평가
Cloud Storage의 Firebase Security Rules는 오류가 발생하면 평가를 계속 진행합니다.
조건부 &&
및 ||
표현식은 오류를 흡수할 수 있으므로 유용합니다.
조건문이 false
또는 true
로 단락되는 경우
로 나뉩니다. 예를 들면 다음과 같습니다.
표현식 | 결과 |
---|---|
error && true |
error |
error && false |
false |
error || true |
true |
error || false |
error |
오류가 발생하는 일반적인 위치: 0으로 나누기, 값 액세스 잘못된 유형의 값을 전달하면 추가합니다.
// Error if resource.size is zero allow read: if 1000000 / resource.size; // Error, key doesn't exist allow read: if resource.metadata.nonExistentKey == 'value'; // Error, no unit 'y' exists allow read: if request.time < resource.timeCreated + duration.value(1, 'y');