Every Google Drive file, folder, and shared drive has associated
Permissions resources. Each resource
identifies the permission for a specific type
(user, group, domain, anyone)
and role
, such as "commenter" or "reader." For example, a file might have
a permission granting a specific user (type=user
) the read-only access
(role=reader
) while another permission grants members of a specific group
(type=group
) the ability to add comments to the file (role=commenter
).
To share a file or folder, the user must have the role of "writer." To share (add a member to) a shared drive , the user must have the role of "organizer."
For a complete list of roles and the operations permitted by each, refer to Roles.
Permission propagation
Permission lists for a folder propagate downward and are inherited by all child files and folders. Whenever permissions or the hierarchy is changed, the propagation occurs recursively through all nested folders. For example, if a file exists in a folder and that folder is then moved within another folder, the permissions on the new folder propagates to the file. If the new folder grants the user of the file a new role, such as "writer," it overrides their old role.
Conversely, if a file inherits the "writer" role from a folder, and is moved to another folder that provides a "reader" role, the file now inherits the "reader" role.
Inherited permissions can't be removed from a file or folder in a shared drive. Instead these permissions must be adjusted on the direct or indirect parent from which they were inherited. Inherited permissions can be removed from items under "My Drive" or "Shared with me."
Conversely, inherited permissions can be overridden on a file or folder on a My Drive. So, if a file inherits the role of "writer" from a My Drive folder, you can set the role of "reader" on the file to lower its permission level.
Capabilities
The permission resource doesn't ultimately determine the current user's
ability to perform actions on a file or folder. Instead, a
Files resource contains a collection of boolean
capabilities
fields used to indicate if an action can be performed on a file
or folder. These fields are set by the Google Drive API based on
the current user's Permissions resource
associated with the file or folder.
For example, when Jon logs into your app and tries to share a file, Jon's role
is checked in terms of permissions to the file. If
his role enables him to share a file, the capabilities
related to the file, such
as canShare
are filled in relative to the role. Then when Jon wants to
share the file, your app would check the capabilities
to ensure
canShare
is set to true
.
Create a permission
The following two fields are necessary when creating a permission:
type
. Thetype
identifies the scope of the permission (user
,group
,domain
, oranyone
). A permission with atype
ofuser
applies to a specific user whereas a permission with atype
ofdomain
applies to everyone in a specific domain.role
. Therole
field identifies the operations that thetype
can perform. For example, a permission with atype
ofuser
and arole
ofreader
grants a specific user read-only access to the file or folder. Or, a permission with atype
ofdomain
and the role ofcommenter
grants everyone in the domain the ability to add comments to a file. For a complete list of roles and the operations permitted by each, refer to Roles.
When you create a permission where type
is user
or group
, you must also
provide an emailAddress
to tie
the specific user or group to the permission.
When you create a permission where type
is domain
, you must also provide a
domain
to tie a specific domain
to the permission.
To create a permission:
- Use the Permissions.create method
with the
fileId
for the associated file or folder. - In the request, identify the
type
androle
. - If the
type
isuser
orgroup
, provide anemailAddress
. If thetype
isdomain
, provide adomain
.
Retrieve all permissions for a file, folder, or shared drive
Use the Permissions.list
to retrieve
all permissions for a file, folder, or shared drive.
Verify user permissions
When your app opens a file, it should check the file's capabilities and render the UI to reflect the permissions of the current user. For example, if the user doesn't have a 'canComment' capability on the file, the ability to comment should be disabled in the UI.
To check the capabilities,
call files.get
with the fileId
and fields
parameter set to the capabilities
field to verify.
For further information on returning fields using the fields
parameter, refer
to Return specific fields for a file.
Determine the source of the role for shared drive files and folders
To change the role on a file or folder, you need to know the source of the role. For shared drives, the source of a role can be based on membership to the shared drive, the role on a folder, or the role on a file.
To determine the source of the role for a shared drive or items within that drive,
use the permissionDetails
field.
This field enumerates all inherited and direct file permissions for the user, group, or domain.
Change permissions
To change permissions on a file or folder, change the assigned role. To change the assigned role:
Call
permissions.update
withpermissionId
of the permission to change and thefileId
for the associated file, folder, or shared drive.In the request, identify the new
role
.
Permissions can be granted on individual files or folders in a shared drive even
if the user or group is already a member. For example, Jon has the
role of commenter
as part of membership to a shared drive. However, your app
can grant Jon the writer
role for a file in a shared drive. In this case,
because the new role is more permissive than the role granted using their
membership, the new permission becomes the effective role for the file or
folder.
Revoke access to a file or folder
To revoke access to an file or folder, call
delete
to delete the permission.
For items in "My Drive," it is possible to delete an inherited permission. Deleting an inherited permission revokes access to the item and child items, if any.
For items in a shared drive, inherited permissions can not be revoked. Update or revoke the permission on the parent file or folder instead.
The delete
operation is also used to delete any permissions directly applied
to a shared drive file or folder.
Transfer file ownership
To transfer ownership of a file, insert or update a permission with
the owner
role and set the transferOwnership
query parameter to true
. When
a file is transferred, the previous owner's role is downgraded to writer
.
Ownership transfers are not supported for files and folders in shared drives. Ownership transfers are implicit when a user moves a file or folder in or out of a shared drive.
Change multiple permissions with batch requests
We strongly recommend using batch requests to modify multiple permissions.
Following is an example of performing a batch permission modification with a client library.
Java
String fileId = "1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ";
JsonBatchCallback<Permission> callback = new JsonBatchCallback<Permission>() {
@Override
public void onFailure(GoogleJsonError e,
HttpHeaders responseHeaders)
throws IOException {
// Handle error
System.err.println(e.getMessage());
}
@Override
public void onSuccess(Permission permission,
HttpHeaders responseHeaders)
throws IOException {
System.out.println("Permission ID: " + permission.getId());
}
};
BatchRequest batch = driveService.batch();
Permission userPermission = new Permission()
.setType("user")
.setRole("writer")
.setValue("user@example.com");
driveService.permissions().insert(fileId, userPermission)
.setFields("id")
.queue(batch, callback);
Permission domainPermission = new Permission()
.setType("domain")
.setRole("reader")
.setValue("example.com");
driveService.permissions().insert(fileId, domainPermission)
.setFields("id")
.queue(batch, callback);
batch.execute();
Python
file_id = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ'
def callback(request_id, response, exception):
if exception:
# Handle error
print exception
else:
print "Permission Id: %s" % response.get('id')
batch = drive_service.new_batch_http_request(callback=callback)
user_permission = {
'type': 'user',
'role': 'writer',
'value': 'user@example.com'
}
batch.add(drive_service.permissions().insert(
fileId=file_id,
body=user_permission,
fields='id',
))
domain_permission = {
'type': 'domain',
'role': 'reader',
'value': 'example.com'
}
batch.add(drive_service.permissions().insert(
fileId=file_id,
body=domain_permission,
fields='id',
))
batch.execute()
PHP
$fileId = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ';
$driveService->getClient()->setUseBatch(true);
try {
$batch = $driveService->createBatch();
$userPermission = new Google_Service_Drive_Permission(array(
'type' => 'user',
'role' => 'writer',
'value' => 'user@example.com'
));
$request = $driveService->permissions->insert(
$fileId, $userPermission, array('fields' => 'id'));
$batch->add($request, 'user');
$domainPermission = new Google_Service_Drive_Permission(array(
'type' => 'domain',
'role' => 'reader',
'value' => 'example.com'
));
$request = $driveService->permissions->insert(
$fileId, $domainPermission, array('fields' => 'id'));
$batch->add($request, 'domain');
$results = $batch->execute();
foreach ($results as $result) {
if ($result instanceof Google_Service_Exception) {
// Handle error
printf($result);
} else {
printf("Permission ID: %s\n", $result->id);
}
}
} finally {
$driveService->getClient()->setUseBatch(false);
}
.NET
var fileId = "1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ";
var batch = new BatchRequest(driveService);
BatchRequest.OnResponse<Permission> callback = delegate (
Permission permission,
RequestError error,
int index,
System.Net.Http.HttpResponseMessage message)
{
if (error != null)
{
// Handle error
Console.WriteLine(error.Message);
}
else
{
Console.WriteLine("Permission ID: " + permission.Id);
}
};
Permission userPermission = new Permission()
{
Type = "user",
Role = "writer",
Value = "user@example.com"
};
var request = driveService.Permissions.Insert(userPermission, fileId);
request.Fields = "id";
batch.Queue(request, callback);
Permission domainPermission = new Permission()
{
Type = "domain",
Role = "reader",
Value = "example.com"
};
request = driveService.Permissions.Insert(domainPermission, fileId);
request.Fields = "id";
batch.Queue(request, callback);
var task = batch.ExecuteAsync();
Ruby
file_id = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ'
callback = lambda do |res, err|
if err
# Handle error...
puts err.body
else
puts "Permission ID: #{res.id}"
end
end
drive_service.batch do
user_permission = {
type: 'user',
role: 'writer',
value: 'user@example.com'
}
drive_service.insert_permission(file_id,
user_permission,
fields: 'id',
&callback)
domain_permission = {
type: 'domain',
role: 'reader',
value: 'example.com'
}
drive_service.insert_permission(file_id,
domain_permission,
fields: 'id',
&callback)
end
Node.js
var fileId = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ';
var permissions = [
{
'type': 'user',
'role': 'writer',
'value': 'user@example.com'
}, {
'type': 'domain',
'role': 'writer',
'value': 'example.com'
}
];
// Using the NPM module 'async'
async.eachSeries(permissions, function (permission, permissionCallback) {
drive.permissions.insert({
resource: permission,
fileId: fileId,
fields: 'id',
}, function (err, res) {
if (err) {
// Handle error...
console.error(err);
permissionCallback(err);
} else {
console.log('Permission ID:', res.id)
permissionCallback();
}
});
}, function (err) {
if (err) {
// Handle error
console.error(err);
} else {
// All permissions inserted
}
});