Security

The content in this guide refers to the newly released version 3 of the library. You can still access the version 1.x guides here.

Version 1.x is now deprecated. We will continue to support 1.x through March 31, 2017 (End of Support - EOS). If you are currently using 1.x in your apps, you will need to upgrade your apps to 3.x before the EOS date. We have created a migration guide to help you.

Every request to your app backend, made by one of our mobile SDKs or another client, is associated with a security context. Kinvey uses this context to determine whether the user making the request is:

  • Who they say they are -- The user is authenticated using their credentials
  • Allowed to do what they're trying to do -- The user is authorized to act on the resource in the manner specified

Access control

Your application will naturally include logic to filter the data displayed to each user. However, this logic resides on the client side, and can be circumvented by a malicious user or ignored by a programming error. This is true whether you build your own backend or not. To give you control and flexibility enforced on the server side, we offer a number of easy configuration options.

Hierarchy

Kinvey allows you to control access via settings at the collection and entity level. These permission settings establish a hierarchy whereby lower level (entity) permissions take priority over higher ones (collection). For example, if a user has read access to an entity, they have that access regardless of the collection level setting. This hierarchy offers useful high-level controls, and robust lower level tuning options.

Common settings

Most developers will not need to do anything, since by default, all data within an app is readable by its users, but writable only by the user who created the entity. This is suitable for many applications as it automatically protects against unauthorized modifications, while keeping the data open.

If your use case requires more privacy, you can set the permission level to Private, which limits the read access to entity creators. When you request an entire Private collection, Kinvey will respond with only the entities that user has access to - the user’s own data. This has the added benefit of saving you the filtering in the app.

Collection level permissions

Below is the full list of collection-level permission settings. They can be modified by visiting the Settings page of your collection.

  • Shared (read-all, write-yours)
    End users of an app can only create and modify their own data, but read all data in this collection. This is the default permission level for any new collection. Previously referred to as 'append-read' permission level.

  • Private (read-yours, write-yours)
    End users of an app can only read, create, and modify their own data. They cannot read any other data in this collection. Previously referred to as 'append-only' permission level.

  • Read Only (read-all, write-none)
    End users of an app can read all data in this collection but cannot create and modify data. Previously referred to as 'read' permission level.

  • Full (read-all, write-all)
    End users of an app can read, create, and modify all data in this collection. Previously referred to as 'write' permission level.

The Full permission level allows anyone on the Internet to modify any data in that collection. Use with caution!

Every request to your app backend, made by one of our mobile SDKs or another client, is associated with a security context. Kinvey uses this context to determine whether the user making the request is:

  • Who they say they are -- The user is authenticated using their credentials
  • Allowed to do what they're trying to do -- The user is authorized to act on the resource in the manner specified

Access control

Your application will naturally include logic to filter the data displayed to each user. However, this logic resides on the client side, and can be circumvented by a malicious user or ignored by a programming error. This is true whether you build your own backend or not. To give you control and flexibility enforced on the server side, we offer a number of easy configuration options.

Hierarchy

Kinvey allows you to control access via settings at the collection and entity level. These permission settings establish a hierarchy whereby lower level (entity) permissions take priority over higher ones (collection). For example, if a user has read access to an entity, they have that access regardless of the collection level setting. This hierarchy offers useful high-level controls, and robust lower level tuning options.

Common settings

Most developers will not need to do anything, since by default, all data within an app is readable by its users, but writable only by the user who created the entity. This is suitable for many applications as it automatically protects against unauthorized modifications, while keeping the data open.

If your use case requires more privacy, you can set the permission level to Private, which limits the read access to entity creators. When you request an entire Private collection, Kinvey will respond with only the entities that user has access to - the user’s own data. This has the added benefit of saving you the filtering in the app.

Collection level permissions

Below is the full list of collection-level permission settings. They can be modified by visiting the Settings page of your collection.

  • Shared (read-all, write-yours)
    End users of an app can only create and modify their own data, but read all data in this collection. This is the default permission level for any new collection. Previously referred to as 'append-read' permission level.

  • Private (read-yours, write-yours)
    End users of an app can only read, create, and modify their own data. They cannot read any other data in this collection. Previously referred to as 'append-only' permission level.

  • Read Only (read-all, write-none)
    End users of an app can read all data in this collection but cannot create and modify data. Previously referred to as 'read' permission level.

  • Full (read-all, write-all)
    End users of an app can read, create, and modify all data in this collection. Previously referred to as 'write' permission level.

The Full permission level allows anyone on the Internet to modify any data in that collection. Use with caution!

Entity level permissions

You can override the collection's access controls on a per-entity basis using acl property.

With Acl you can make an item globally writable, globally readable, or supply a list of user id's that are able to read or write the data.

import Kinvey

/// Event.swift - an entity in the 'Events' collection
class Event : Entity {

    var name: String?
    var date: NSDate?
    var location: String?

    override class func collectionName() -> String {
        return "Event"
    }

    override func propertyMapping(map: Map) {
        super.propertyMapping(map)

        name <- ("name", map["name"])
        date <- ("date", map["date"], KinveyDateTransform())
        location <- ("location", map["location"])
    }
}
import Kinvey

/// Event.swift - an entity in the 'Events' collection
class Event : Entity {

    var name: String?
    var date: Date?
    var location: String?

    override class func collectionName() -> String {
        return "Event"
    }

    override func propertyMapping(_ map: Map) {
        super.propertyMapping(map)

        name <- ("name", map["name"])
        date <- ("date", map["date"], KinveyDateTransform())
        location <- ("location", map["location"])
    }
}

Global Access Control

You can make an entity visible and/or writable to all users of an app using globalRead and globalWrite on the Acl property and then saving the object.

event.acl?.globalRead.value = true // anyone can read
event.acl?.globalWrite.value = true // anyone can modify

Reader/Writer Lists

You can add other users by id to a list of readers or writers. Users with matching ids will have access that other users will not.

if let user = Kinvey.sharedClient.activeUser {
    let userQuery = UserQuery() {
        $0.email = "<#my-friends@email.com#>"
    }
    user.lookup(userQuery) { users, error in
        if let myFriend = users?.first {
            event.acl?.readers?.append(myFriend.userId)

            //add 'myFriend' to the writers list as well
            event.acl?.writers?.append(myFriend.userId)
            //... and then save the event
        }
    }
}

Gotchas

Write implies delete

If a user has write access to an object, they can delete it. They cannot, however, set permissions themselves. Only the creator can give and take permissions for the respective entity

Write does not imply read

Having write access does not imply read access. To grant both kinds of access, simply call the two methods.

Master secret is "root"

The master secret has read and write access to all data, and can modify any permissions setting at any level. Entity creators have no mechanism to take that access away. (A reminder, never embed the master secret in the app). To import data from a legacy data source, use the master secret and set the ACL such that it preserves data ownership and access level.

Use cases

If you have collections that only hold entities that the app developer or administrator can create or modify, such as a daily deal, or a blog post, you would want to set the access level to Read Only. This allows read access to user credentials, and write access only to the app developer using the master secret.

If you have some kind of watch list functionality, where app users express interest in certain items by adding them to their watch list, and you store those in a separate collection, you might want to set it to Private. This means that any app user can append (create their new watch list and modify it) to the collection, but not read another user's watch list. If you want the watch list to be visible to other app users, you could set the collection to Shared.

The Full collection permission level allows any app user to create and modify any object. By itself it may seem too open, but combined with the right entity level settings it can be an effective approach for some apps.

To enable a social app, you can make use of the fine grained permissions described above. For example, set the collection holding user profiles to Private and let users make their profiles public via 'global read' or open them only to their friends, via 'readers'. Note, the lookup method will always allow an app user to discover other users.

Locked-down Users

The app administrator has the ability to lock-down a user. When a user is in locked-down state, any requests that are authenticated with this user's credentials, or that attempt to log the user in will fail. Additionally, the library clears all local data when it detects a user in a locked-down state.

Got a question?