WWDC2015 Session 703

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
>> KATIE SKINNER: Hi, everyone.
My name's Katie Skinner,
and along with Jason Novak,
we are going to be
talking about privacy
in your app this afternoon.
We are both members of Product
Security and Privacy at Apple.
That means we work with
teams all across Apple
to build privacy into
our apps and services.
A few of the teams that I work
closely with are Apple Pay,
Siri, Proactive Assistant,
Health,
and our newest OS, watchOS.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and our newest OS, watchOS.
First I am going to
talk a little bit
about why privacy matters at
Apple and how we think about it.
At Apple, we see
privacy as a human right.
That's a guiding principle
that we take every day
into how we design our apps,
our services, and new versions
of iOS, OS X, and watchOS.
Users want their
privacy respected
when they use our
products, and all developers,
everyone in this room,
shares that responsibility.
So when you are building
your apps,
be mindful of user privacy, and
build privacy into your apps.
Not only at Apple are we focused
on building great products,
we also are focused on
building great tools for you,
the developer community,
to make it easy for you
to respect user privacy
and build privacy
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to respect user privacy
and build privacy
into your apps and services.
At the end of the day,
all of our success relies
on our relationship
with our users.
And trust is key to
maintaining that relationship.
We've all read stories in
the press about breaches,
about misuse of user data,
and nobody in this room wants
to be the next one in the news.
Our platform is a place
where users have excited
about new experiences, excited
about downloading
new applications.
And it's all about keeping
our app ecosystem healthy
and thriving.
And the trustworthiness of
all of you is part of that.
So be trustworthy
with our users.
Now, users trust us with
lots of sensitive data.
And we need to be good
stewards of their data.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And we need to be good
stewards of their data.
And architecting for privacy is
the place to start to do that.
Now, all data should
have a retention policy.
Now, how do you come up
with that retention policy?
The place to start is how
you will use that data.
Now, if you are no
longer using that data,
it's no longer serving
a user need,
then you should delete
that data.
All data that you are
storing and the more data
that you store makes you a
richer target for attackers,
a more valuable target.
So only collect the
data that you need.
I believe that all data
collected carries risk,
so you need to balance the
value that you provide to users
with the risks inherent in
collecting and storing data.
Now, you can mitigate this risk
by applying data
minimization techniques.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by applying data
minimization techniques.
To learn more about the list of
techniques and to see examples
on how to apply them, go and
watch User Privacy in iOS
and OS X from last year's WWDC.
Aggregation, de-resolution,
these are all ways
to reduce the risk for
the data that you retain.
But which techniques
should you apply?
The place to start is what
is the use of the data?
How are you going to use it?
What questions are
you going to answer?
What decisions is
this data driving?
And if you can't come up with
an answer to this question,
you can't think of anything,
then you shouldn't be
retaining this data at all.
Apply the last technique
on the list, minimization,
and don't collect or
transfer the data at all.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, for the data that
you decide is actionable,
all data sent off device
should be protected in transit.
Later Jason will talk about
App Transport Security,
which is a new way in
iOS 9 to make it easier
to communicate securely
with your services.
To reduce the risk, avoid
transferring data off device
when possible, especially
think twice
about sensitive data categories.
This includes things
like health data.
For example, during a cycling
workout, there's information
like the user's heart rate,
the distance traveled,
maybe the user's height and
weight, calibration data,
and all of that is processed
on the paired devices
to show what calories were
burned during that workout.
None of that data is sent
to server for processing.
Now, data needs to be
protected not only in transit
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, data needs to be
protected not only in transit
but also when persisted.
First think about does the
data need to be stored at all?
Can it be transient?
Can it be stored only in memory?
Or does it need to
be written to disk?
On iOS and watchOS, take
advantage of data protection,
which I will be talking
about more later.
If you are storing
your data server-side,
make sure you encrypt
your data at rest.
With CloudKit, we make
it simple to do this.
Think about what identifiers are
sent and stored with your data.
Jason's going to talk
in depth later about how
to choose an appropriate
identifier.
Now, you want to be
clear with your users
about what you are doing
with your data, their data,
how you are using it, if you are
sharing it with third parties,
and this is all part
of transparency.
Making sure users
understand what's happening,
avoiding any user surprise.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, one way to do this
is to be clear to users
about what data is being
collected or stored.
Give users a way to
inspect their data.
Also, when you're
collecting the data
or when you give users a
choice, it's at that point
that you really want to
give them the information
to make a good choice.
You can do that with
things like purpose strings.
When users are deciding
if they want
to grant you access to,
maybe, their photos.
Also, you want to
give users control.
Give them a way to
remake their decision.
If they decide later that
they want a different decision
for themselves.
Also, give them a chance
to reset information you
store or even delete.
Now I am going to talk about
some updates to our platforms
to improve user privacy.
I am going to talk about
changes in iOS, OS X,
and some of the foundational
bits for watchOS.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and some of the foundational
bits for watchOS.
So first on iOS, we are going
to go back to last year.
Last year, we began using
privately assigned MAC addresses
for certain types
of Wi-Fi scans.
In iOS 9, we've increased
the number of scans
that use privately
assigned MAC addresses.
Note if your functionality
is based on working
with an external piece of
hardware, make sure to test
on iOS 9 because you cannot rely
on the MAC address
before authentication.
Now, simply put, we think
what apps are installed
on a user's device
are their business.
Users use their devices for lots
of things, and they have lots
of reasons for what kinds of
apps they want to install,
from health to financial
to home.
Now, what apps a
user has installed
and what can be gleaned from
them can be very sensitive.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and what can be gleaned from
them can be very sensitive.
Trying to detect what
apps a user has installed,
either to identify them
or to glean information,
is contrary to the
iOS security model.
Ultimately, the iOS security
model the apps are isolated.
They live within their own
sandbox, protecting them
from other apps and processes.
Trying to determine what
apps a user has installed
in their device is a subversion
of the iOS security model.
Now, along those
lines, the behavior
of canOpenURL is
changing this year.
The purpose of canOpenURL
is to determine
if an app can open a
given URL resource.
This can be used to
support functionality,
like revealing new
things that a user can do
if an app is installed
in the device.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
if an app is installed
in the device.
One of the things you should be
moving towards are extensions
and universal links.
They both support a lot
of the same functionality,
and we encourage
you to move to that.
But if you continue to use URL
schemes when you build your app
for iOS 9 and you want to call
URL schemes, you will now need
to declare them in
your apps Info.plist.
There is new key,
LSApplicationQueriesSchemes,
and here you will
need to add the list
of schemes you want
to are canOpenURL on.
Now you don't need to change
handle calling canOpenURL.
The actual API is not changing.
But when you call canOpenURL, it
will check your app's Info.plist
and see if the scheme you
are calling is declared.
So let's say you declared it.
When you call canOpenURL on
that scheme, it will return true
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
When you call canOpenURL on
that scheme, it will return true
if there is an app installed
that does support the scheme.
Now, if there is not an app
installed, it will return no.
So what if you didn't
declare the URL scheme.
No matter if there is an
app or there is not an app
that supports it, you will
always be returned no.
So for apps that are linked
before iOS 9 and are running
on iOS 9, they will be given
50 distinct URL schemes.
When you call the
subsequent 51st scheme,
you will be returned
the value no.
These 50 URL schemes
are not restarted
when the user restarts
the device.
One alternate that I mention
that is new this year
is universal links.
The great thing about
universal links is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The great thing about
universal links is
if the user has the
app installed,
the link will open there.
But then there's
also a fallback.
If the app is not
installed, it will open
in the webpage of that app.
There's also changes
coming to sysctl this year.
Sysctl is a low-level
API used for querying
and setting system information.
It's designed to allow processes
with appropriate privileges
to view information,
but as I said before,
apps on iOS are not privileged
to see other apps' information.
So there is a change to
the iOS sandbox this year,
and now there will no longer
be able to call kern.proc,
kern.procargs, kern.procargs2
and see data
from any other processes
then one's self.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This year, on both iOS and OS X,
we will have a new extension
point for content filtering.
Your block list -- the block
list will apply to both Safari
and any apps that use
SafariViewController.
You should go and test
with popular extensions
to understand the
impact this will have
on your application
or your webpage.
You should always be prepared
for part of your content to fail
to load and handle
it appropriately.
Next, on OS X, we are
changing the cookie policy.
As of Yosemite, where
cookies could be shared
across all applications
and processes,
now, cookies are local.
They are local to
a single process,
and they are not shared.
Note: If you have shipped your
application in the App Store,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Note: If you have shipped your
application in the App Store,
there's no change for you.
You are already in this state.
If you use Web Clips
or Dashboard widgets,
please test on OS X El Capitan.
Now I am going to talk a little
bit about our newest platform.
Over many years, we've seen
iOS and OS X evolve and grow.
It's that experience that drove
us to focus on making sure
from the start that we laid
the appropriate groundwork
for privacy and security
on this newest platform.
We leveraged existing
technologies,
like data protection,
our just-in-time alerts,
and we think that these
devices work closely together.
The user has a single
relationship
with the two devices,
and so that's why lots
of the settings are
shared across.
This also includes
your privacy settings
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This also includes
your privacy settings
for native WatchKit apps.
So whether the user is
interacting with your app
on iOS, as a Glance, as a
third-party complication,
the same privacy settings apply.
We believe that the user has
a single trust relationship
with you as an app developer.
They don't think
differently about, oh,
can they access my
photos on the Glance.
They have one trust
relationship.
They trust you to access
that data and protect
that data or they don't.
So we think that this
is important to focus
on making sure that you
embed and think about privacy
from the beginning because your
Glance may become the place
where users interact with
your app the most often.
Also, in watchOS 2,
Keychain is now on Watch.
Now I am going to hand it
over to Jason, who is going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now I am going to hand it
over to Jason, who is going
to talk more about how
to choose an identifier.
[ Applause ]
>> JASON NOVAK: Thanks, Katie.
Now I am going to
talk a little bit
about identifiers
on iOS and watchOS.
This is a topic that
we've covered before
in previous presentations,
and you should review
last year's WWDC talk
to get a more in-depth
look into.
But I thought it was
important to go over some
of the lessons we learned
from iOS before discussing
how we brought identifiers
to watchOS.
So identifiers are powerful.
They are powerful because
in and of themselves,
they can reveal something about
a user if you use something
like a user's name,
phone number,
or email address
to identify a user.
You can build a more
privacy-friendly identifier
by using things like randomly
generated numbers or a UUID
if you need a structured
random number.
While a random number or UUID
doesn't identify a person,
depending what you
log against it,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
how frequently you
rotate identifiers,
and what controls a user has,
over time the identifier
can be de-anonymized
as you can log a lot of
different kinds of data
that may be identifying to a
person, like app activities,
search queries, messages,
or location,
depending upon what
your app is doing.
And what this means is that
all identifiers carry risk.
Even though an identifier
itself may be anonymous,
if the data you hold
against it isn't,
then if there is a data
breach, you still have to deal
with a harm to customers'
privacy,
and the ensuing reputational
damage
as you'll lose customer trust.
When I say data breach, that may
cause you to think about hackers
or other nefarious forces,
but it may be as simple
as an unencrypted laptop
stolen out of the back of a car
or backup tapes falling
off the back of a truck.
As a result of the power
identifiers, Apple spent a lot
of time thinking about
how identifiers operate
and some best practices.
So first, before you
use an identifier,
ask yourself: Do you need one?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
ask yourself: Do you need one?
Can you structure your
data collection in some way
that you have a database
or dictionary of values
that you are storing server side
that the client sends up a value
to your server and then you just
increment a counter server side?
If you determine that you
really do need an identifier,
think about what
you are identifying
and for how long you
need to identify it for.
Are you identifying a
session and just trying
to correlate activities across
a single launch of your app?
Are you trying -- and can you
rotate the identifier every time
the app opens or closes?
Are you looking at temporal
activity and you need
to rotate the identifier
every 5, 10, 15 minutes?
We know that rotating
identifiers has a lot
of privacy-preserving power
as it prevents the correlation
of data over time,
and we will walk
through an example
of that later.
If you are identifying a user,
how are you making it clear
to the user that you are
identifying them as opposed
to an installation on device?
Are you having them create
an account with your service?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Are you having them create
an account with your service?
Are you having them log in?
Are you using words in the UI
that make it very clear to them
that this is about
their experience?
And after you thought about
how you are explaining this
to users, have you
really thought
about the risk you are
taking on in collecting data
that is associated with
an individual's identity?
Finally, if you are
trying to collect data
about an installation of
your app on a device divorced
from these other notions
of users or sessions,
have you designed your
metrics to support the cases
that we know occur with
a user and their device,
such as uninstalling an
app or installing an app
on a secondary device or backing
up and restoring across devices
and how the privacy preservation
of a user that occurs there
in terms of the identifiers
being reset
or persisting affect
your metrics?
Finally, you should consider
how you scope your identifiers.
It's easy to construct a world
where a persistent
identifier is used to track all
of the user's activities
across properties,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the user's activities
across properties,
but then a user's
privacy is minimized.
Lots of data is collected
against a single identity
that may never change that
has different contexts,
different meanings in
different contexts.
Moreover, users may not want to
be tracked across all properties
under a single identity.
Contemplate scoping
your identifiers
so that you have
different identifiers
for different purposes with
different data associated
with them with different
retention periods.
Now I am going to walk
through an example
of a specific architecture
of identifiers
that increases your privacy
and decrease the
risk you might face.
It's easy to design a search
service that logs all data
to a user identifier, but
then if this data is breached,
then even if the
identifier is anonymous,
it allows for the ready
re-identification of a user,
as among other things,
users search for themselves,
and this scenario may result
in a significant
loss of user trust.
For example, in this case,
the identifier is anonymous.
It's 123. But we can see a
fairly clear set of facts.
User 123 is thinking about
getting engaged -- probably --
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
User 123 is thinking about
getting engaged -- probably --
probably this past Saturday.
They are probably not from San
Francisco as they are looking
for a flight from San Francisco.
They are probably going to WWDC.
And they may be John Appleseed,
they may be interested
in John Appleseed.
We don't know.
But given more data, we
could probably figure
out if this was a
vanity search or not.
On the other hand, if your
search service uses rotating
identifiers, then even if
data is released, the exposure
for a given user is minimized
as the identifier
rotates over time.
In this case, if the identifier
rotated every 15 minutes,
we can't necessarily say
that user 123 is the same
as 456, is the same as 789.
So now I am going to talk
about persistent identifiers
for a moment, and because of
the risk that they present
to user privacy in
terms of the ability
to permit long-term tracking of
users, they are not available
on iOS and watchOS by design.
Apple tries to surprise
and delight its customers,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Apple tries to surprise
and delight its customers,
and customers aren't delighted
when they are being tracked
without their knowledge.
It's not in line with
users' expectations
that they are being tracked by
an app under the same identity,
even after they have uninstalled
the app and reinstalled it
or if they've done
something more destructive
like erase their device.
And finally, because persistent
identifiers are persistent,
users don't have
control over them,
and as Katie was saying
earlier, we think of control
as a very important
part for user privacy.
To try and balance the needs
of developers to identify data
and with the privacy of
users, we've developed a set
of purpose scoped
identifiers on iOS
so that developers can collect
the data they need and use it
in the analytics and
advertising context while
at the same time users have
control to reset the identifiers
and break the relationship
between their current activities
and whatever data has been
historically collected
about them.
At the app level, we enable this
by resetting the vendor
identifier or the IDFV
after a user has uninstalled
all apps from a given team ID.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
after a user has uninstalled
all apps from a given team ID.
And on the advertising context,
we give users the ability
to reset their advertising
identifier by going to Settings,
Privacy, Advertising,
and tapping the Reset
Advertisement Identifier.
As a result a user can reset
the identifier on their device
without erasing all data on
it and they break the link
with whatever data has been
historically collected.
With watchOS 1, the vendor ID
and the advertising ID
were actually on the iPhone
as the WatchKit extension
itself ran on the iPhone.
With watchOS 2, you will
need to sync the vendor ID
and advertising ID
from the iPhone
to the Watch and use it there.
And you will need to
maintain the vendor ID
and advertising ID up-to-date.
So now I am going to go
over some best practices.
Determine if you need
an identifier at all.
Can you just send up a value and
increment a server-side counter?
Collecting data against an
identifier brings responsibility
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Collecting data against an
identifier brings responsibility
as it brings risk.
And if you can collect just a
value in increment encounter,
you have significantly
increased user privacy
and derisked your
data collection.
Use a properly purposed
scope identifier.
Determine if you need to
identify a session, a user,
or a device and use an
identifier of the proper scope
for your app's purpose.
iOS and watchOS offer
identifiers for you,
so use them instead
of building your own.
Trying to build a
persistent identifier
that survives device reset
and other destructive actions
like removing your app is bad
for user privacy and
bad for your app.
If you are using private APIs to
build a persistent identifier,
you are in violation
of the App Store terms,
and there will be consequences.
Finally, follow the
guidelines for the identifiers
that are provided, and one
of the most important
guidelines you can follow is
to check the value of Limit Ad
Tracking before you call the
advertisingIdentifier and to
always get the current value
of the advertisingIdentifier.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the advertisingIdentifier.
A user can reset the value
of the advertisingIdentifier
at any time, in addition
to enabling ad tracking.
Which also causes a reset of
the advertisingIdentifier.
Because of this, you
should always be sure
that you have the current value,
and you should never cache it.
Finally, we are going to talk
a little bit about reporting.
We know that many of you
have reporting obligations
to your partners, but
we think it's important
to maintain user privacy when
reporting to third parties.
We thought a lot about
how to report on users,
and you can see a lot
of our learnings
embedded in App Analytics.
And there are sort of
three big ideas here
that you can implement
when reporting.
Report insights about
your users.
Report aggregates.
And set a threshold.
What do I mean by
report insights?
Instead of if a partner
wants to know
who uses your app frequently
and say give us all data
about your app's usage so
that they can calculate that,
instead, agree upon a
definition of common usage,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
instead, agree upon a
definition of common usage,
run that calculation,
and on your data,
and provide the results of
that calculation instead
of giving over the raw data.
The next step to protecting user
privacy would be to aggregate.
Instead of saying which
users are frequent users,
say how many frequent users
you have, what percentage
of your user base
are frequent users.
And finally, require
thresholds in reporting.
If you are going to report
that you have one frequent user
and you have one user of
your app and you are going
to provide some information
about them
from an audience
standpoint, like zip code,
you have effectively
de-anonymized your user.
Before you provide
personal information be sure
to have a threshold, so that
you're not de-anonymizing a
person, and they're in a group.
I am now going to explain some
best practices on how to prompt
for user data and
then extend those
to the Watch Just a refresher,
on iOS and OS X, when you want
to access data classes,
the operating system doesn't
give access to that data
until the user makes a
decision as to whether or not
to give your app
access to that data.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to give your app
access to that data.
So that it's clear to users why
an app needs this data and so
that you can be transparent
with users about your collection
and use, we provide you
with a place in the prompt
where you can provide
an explanation.
This is called a purpose string.
You can set them for the
various protected data classes
in your apps and
Info.plist, and we think
that if users understand why
you are asking for their data,
they are more likely to make the
choice that's right for them.
As Katie said earlier, given the
limited real estate available
on the watch and our perspective
on transparency and consent
to control, a lot of
thought went into how apps
on the watch could
access user data.
First, just like
on iOS and OS X,
apps on watchOS can't
access a user's data
until the user has
approved that.
Unlike on iOS or OS X, on
watchOS, a user can't accept
or deny a just-in-time
prompt on the device itself.
Rather, they are
directed to their iPhone.
As Katie was saying, we think of
the iPhone and the paired Watch
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
As Katie was saying, we think of
the iPhone and the paired Watch
as a tightly coupled experience,
and the privacy decisions
that users make on one platform
affects them on the other.
Given the limited real
estate on the watch,
we thought that it made more
sense to present the choice
on the iPhone, where the
user will see the prompt
on the larger screen,
including the purpose string,
explaining why your iPhone app
and Watch app want
access to that data.
Unlike in iOS where you
get a yes or no answer,
you can prompt, get dismissed,
or otherwise not have the user
make a choice when you prompt
from the watch, and as a result
be left in an unset state.
In this unset state, you will
be able to prompt again later.
Just to give a concrete
example of that unset state,
a user could go on a run with
their Watch but not their Phone,
launch your app on the Watch.
Your app could prompt.
The prompt would be dismissed.
And your app would
have to continue to run
without access to that data.
But at a later point in time,
your app could prompt again.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But at a later point in time,
your app could prompt again.
Now, as Katie said
earlier, the settings,
including your privacy settings,
are shared between the
Watch and the iPhone.
And we think that users
have a single relationship
with your app, a single
relationship with the iPhone
and the Watch, so as a result,
we've combined these
single relationships
into a single relationship
of settings for the iPhone,
the watch, and your app.
And this is something
that exists elsewhere
in our platforms.
On iOS, if a user makes a
privacy decision for your app,
then all facets of your app
have access to that data.
If you prompt for a
location in your app,
your extensions can use
it, and if the first time
that a user encounters
a prompt for your app is
in the extension, your app will
also have access to that data.
On the Watch, the decisions that
a user makes carries over to all
of your Watch app, the
app itself, your Glance,
and your Complication.
When a user gives permission
for one aspect of your app,
they give permission for
all aspects of your app.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
they give permission for
all aspects of your app.
Now that you know what data is
available on iOS, OS X, watchOS,
and how to prompt for them,
we think it's also important
to consider how to protect user
data once a user has given you
access to it with a
new set of OS releases.
We have new security
features you should leverage
and be aware of.
The first of these is
App Transport Security.
To secure user communications
by default,
we introduced App
Transport Security
to iOS 9 and OS X El Capitan.
By default, your communication
through higher level
APIs will need
to be encrypted using
TLS version 1.2
with forward secrecy.
If you try to make connection
that doesn't follow
this requirement,
an error will be thrown.
If your app does need to make a
request to an insecure domain,
you have to specify this domain
in your app's Info.plist.
This will be gone into more
detail in the Networking
with NSURLSession tomorrow at 9
a.m. in Pacific Heights as well
as in the security talk
later this afternoon.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If you do want to
declare an exception
to App Transport Security, you
need to declare the exception
in your app's Info.plist
and then optionally set one
or more of these keys.
Now I am going to talk
about rewards cards.
With iOS 9, rewards cards
can now be presented
with Contact list transactions.
We know that some rewards cards
use a person's phone number,
email address, or other
personally identifiable data
as the identifier for
the rewards cards.
So to protect user
privacy in the presentation
of rewards cards and
Contact list transactions,
we provided developers with an
easy way to encrypt this data
when it goes over the Contact
list transaction channel.
All you have to do is
modify your pass.json
with this new nfc dictionary
where you specify the message,
the identifier, and your
public encryption key.
From there, iOS takes care of
the encryption of the message
for you when the
rewards card is presented
in the contactless payment.
With the App Search, App
history, and App links in iOS 9,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
With the App Search, App
history, and App links in iOS 9,
it now means you
can now store data
about your app outside
of your app.
As a result, you have
to be a good steward
and protect the data
for your users both
when it is inside your app
and when it is stored
outside of your app.
There's a great talk
about this on Wednesday
at 11 a.m. Please go check
this out as they will go
into much greater depth
than I can, but I am going
to talk briefly about two ways
an app can have data indexed
and the privacy impacts of them.
The first is NSUserActivity,
which is an API introduced
in iOS 8 to support Handoff.
In iOS 9, we extended it so
you can use NSUserActivity
to create views of your app this
can be indexed and then searched
for by user to return to.
For example, in your Recipe
app, when a user looks
at a poutine recipe, you
can create a NSUserActivity
for that view and
have it indexed.
Then when the user searches for
poutine on their phone later,
one of the results
will be a link
to the recipe they
were looking at before.
Think of it as handing off to
yourself in the future instead
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Think of it as handing off to
yourself in the future instead
of on to another machine.
We thought about how to
make search privacy friendly
from the ground up, and
part of how we did so was
to have the default
be not to index data.
That's right.
By default, NSUserActivity
continues to be for Handoff.
If you want to make a
view that's searchable,
you have to set the
eligibleForSearch property
to true, and if you want to make
that view publicly indexable --
and we will get into
that later --
you have to make
that eligibleForPublicIndexing
property set to true as well.
The other property
that you should set
when you are making data
indexable is the expirationDate,
since as Katie discussed
earlier,
part of protecting user
privacy is protecting their data
by deleting it when it's no
longer relevant to the user.
So now I am going
to talk a little bit
about NSUserActivity
and public indexing.
NSUserActivity are a
great light-weight way
to make your apps searchable.
We made indexing privacy
friendly by not indexing it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We made indexing privacy
friendly by not indexing it
by default and leaving it to
developers to determine whether
or not to index a specific view.
But we understand that
some developers have apps
that contain public
content that they want
to be searchable on all devices.
To enable this, we
came up with a way
to protect user privacy while
also indexing additional data.
When you make a view
eligible for search
and then mark it eligible
for public indexing
if it contains only
publicly available data,
then when a user searches for
that view and engages with it,
a hash of that view
is sent to Apple.
After multiple devices,
hash this view
and send the hash to Apple.
Eventually, when the
threshold is exceeded,
the actual view will
be sent to Apple,
and this is so that views
accidentally marked public
aren't unintentionally sent up.
That's NSUserActivity.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
That's NSUserActivity.
I am going to talk a little
bit about CoreSpotlight now.
CoreSpotlight now is a new
API in iOS 9 that you can use
to make user content
in your app searchable,
things like Mail,
Contacts, Calendars.
This is derivative
data, and you need
to protect it the same way you
protect underlying data yourself
in your app.
The first up here is a set data
protection class on it just
as you do data in your app.
The next is to practice
data management
with the derivative
data in the index.
You can store -- first you
should store relevant user data
-- for instance,
does anyone need
to see drafts or
deleted documents?
When a user updates
documents in your app,
you should update the copy of
those documents in the index.
When a user deletes a
document in your app,
you should delete the
document in your index.
Because users have multiple ways
of deleting documents in apps,
like deleting all
files of a type
or of a folder we have made it
easy to delete multiple items
at once or to delete
all items from search.
That's a brief overview of some
of the new privacy
protecting features in iOS 9.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the new privacy
protecting features in iOS 9.
I am now going to hand it over
to Katie to talk about some
of the existing technologies
you should be adopting
if you haven't already.
[ Applause ]
>> KATIE SKINNER: Thanks, Jason.
I want to highlight a few
of the existing technologies
that we have that makes it
easy to protect user data
without having to do work
like writing crypto
primitives yourself.
Touch ID is a great
way to protect your app
or protect data within your app.
You can use Apple Pay in app to
make it so you don't have to go
through the process of creating
and accepting user data
and credit card data.
Now I am going to dive
a little bit deeper
on privacy policies
and data protection.
In addition to protecting
your user's data technically,
it's important to explain
to users how you are going
to use their data
and if you are going
to share it with a third party.
We actually require privacy
policies for certain types
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We actually require privacy
policies for certain types
of applications, including
apps that link to HealthKit.
We make it easy for you to
include a privacy policy.
On iTunes Connect, you
just put in the URL,
and then it will show up
on all of our App Stores.
It gives users a chance to read
your privacy policy before they
make a purchase decision.
You can use iOS's built-in
data protection classes
to encrypt your data to
keys that are derived
from the user's passcode.
This is incredibly
powerful encryption,
and you can easily
leverage it without having
to write any crypto
code yourself.
Now, every iOS, data
protection is implemented
by managing a hierarchy of keys.
It builds on the hardware
encryption that's built
into every iOS and
watchOS device.
Data protection is
controlled on a per-file basis,
so each file is assigned
to a class.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so each file is assigned
to a class.
Accessibility is determined
whether the class keys have
been unlocked.
So there are four data
classes, and I am going
to go through each one.
But the one that you
may be most aware
of is NSFileProtectionComplete
UntilFirstAuthentication.
As of iOS 7, all
third-party app data
by default is this data class.
Now, your apps can't
run until after boot,
until after the user
puts in their passcode.
So all of your data should
at least be this protection.
We know that some developers
are using no protection,
but there's no reason,
no value for doing that.
So I'm going to quickly go
through the different data
classes in the behavior.
As you can see, with
no protection,
even if the user enters
the passcode or not,
the data is always unlocked.
It's always accessible.
Lastly -- so next, protected
until first authentication,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Lastly -- so next, protected
until first authentication,
this is your default class.
Now, it's not accessible
on boot,
but as soon as a user
enters their passcode,
the data is accessible, and
then it's still accessible
when the device is locked.
Next is protected until open.
This is designed for
data that comes in
and is sensitive while
the device is locked.
So there's two types of
access, reading and writing.
So the device boots,
and there's no access.
The user enters their passcode.
Now you can both read and write.
The device locks again.
You are unable to read, but
you can still write data.
Lastly, complete protection.
Now, this is for most
sensitive kinds of data,
including health data,
financial information.
When the device boots,
the data is unaccessible.
When the user enters their
passcode, the data is available.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
When the user enters their
passcode, the data is available.
The device locks, the data
is no longer available.
This is a great chart to
look at later to think
about which data protection
class you should be using.
And lastly, make sure you test
with data protection enabled.
You can check this by going to
Settings, Touch ID & Passcode,
scrolling down to the bottom,
and see if data protection
is enabled.
Now, we've talked about a
lot of things, and you need
to make sure that you take your
apps and test on iOS and OS X.
You want to understand the
impact to these changes
and make sure you are still
providing a great experience
for your users.
Prompt with purpose.
Make sure to minimize data
and keep it up to date.
Leverage some of the
platform technologies
that we talked about today.
And lastly, user privacy is
our shared responsibility.
We have to do this
together, so both us and you.
It's our responsibility
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's our responsibility
to protect the privacy
rights of our users.
Thank you very much.
[ Applause ]