The Art of Authentication & Authorization

So today I'm going to talk to you about the art of authentication and authorization.

Now, when tackling an auth project, adding auth to an app can often look something like this.

I really like this tweet from Nick Craver.

It says, "step one.

Are you ready to add work on the auth code?

Step two.

Yes.

Bring it." And then step three, the lived experience often ends up looking something a little bit more like this.

Now here's the thing.

The first step to adding auth is often Googling how to do it.

And then you're supposed to kind of just magically know and understand everything else that goes into coming up with that fully realized auth solution.

And this is actually feasible.

It's basically feasible if you use something like an identity as a service provider or an identity solution, maybe you've even implemented auth before doing this, but what was actually happening and why was a black box to you.

And you did a bunch of things, but you weren't confident in your knowledge of why those things worked, the way that they did.

So today I really want to kind of take you deeper.

I want to show you how to draw the owl by going into the foundational concepts behind authorization and authentication.

And like I said, you don't need to be an expert in all of this to get to a productive end result.

But since you're here, I assume that you're interested in learning more.

So we're going to start with an introduction to commonly used open standards.

I'm going to go through this in an approachable way.

I'm going to provide you with a foundational knowledge on standards based auth.

So we're going to start with the concept of identity.

Now, my job used to be working in identity and when I would tell like family members that they thought that I worked at the secretary of state issuing driver's licenses, or maybe I helped people recover from identity theft or credit card fraud.

But the reality is I worked with digital identity and digital identity is defined as a set of attributes that define an individual user in the context of a function that's delivered by a particular application.

Which is a bunch of words that kind of sound meaningless.

But let me give you an example.

Let's say that you are an online shoe retailer.

The digital identity of your users might be their credit card number, their shipping address, and their purchase history.

Because that's what's applicable in the context of your application.

So when we say authentication, what do we mean?

Well, in a broad sense, authentication refers to the process of verifying that the user is who they say that they are.

Then what's authorization?

Well, authorization is about granting or denying rights to access resources.

And when we talk about authorization, we need to talk about OAuth.

OAuth2 standards are very clearly defined, but the document itself is really dense.

So what I'm going to do here is I'm going to go over the broad, applicable concepts.

And in order to do that, I kind of need to do a little bit of a history lesson because things were a lot different before OAuth.

OAuth 1 was established in December of 2007.

And before that, if we wanted to access third party resources, it looked a little bit like this.

I'm going to give you an example here.

Let's say that you use a web app called HireMe.

Let's say you also use a web app called MyCal in order to manage your personal calendar.

Maybe HireMe wants to add an event to your MyCal.

Maybe it's an appointment to meet with a recruiter for an interview.

What's going to happen is HireMe is going to use a browser to ask you to provide your MyCal username and password to HireMe.

HireMe then would take your MyCal credentials and use them in order to access the MyCal API.

This now means that HireMe can access MyCal's API to do things like create calendar events by using the credentials for MyCal that you provided to HireMe.

Now this approach relied on sharing a user's personal credentials from one app with a completely different application.

In general, this is kind of for obvious reasons, not a good idea.

For one thing, if HireMe doesn't do their due diligence, they have a lot less at stake than MyCal.

If they leak your MyCal credentials than HireMe can kind of get away with saying, oh, whoops, my bad.

But for MyCal, it might actually be catastrophic.

Now also HireMe just has way too much access to the MyCal API.

You gave your MyCal credentials to HireMe, that means HireMe can do everything in MyCal that you can do-they could change your name.

They could delete your events.

They could completely create different settings for you.

So this problem gave birth to OAuth.

We needed a way to solve this problem.

I'm specifically going to talk about OAuth 2 in this talk.

And OAuth 2 is an open standard for performing what we call delegated authorization.

Using OAuth myCal can do things like delegate authorization to HireMe in order to grant HireMe limited access to the MyCal API without incurring the risks that I talked about.

And it does this by using something called an authorization server.

An authorization server is a set of endpoints to interact with the user and issue tokens in its simplest definition.

So let's go back to our scenario with HireMe and MyCal.

Only, now let's view this through the lens of using OAuth 2.

Now using OAuth 2 MyCal has an authorization server.

And let's assume that HireMe has already registered as a known client with MyCal.

So MyCal is already aware that HireMe is going to be asking for access to its APIs.

Let's say that you are logged in with HireMe already and HireMe wants to set a calendar event on your calendar in MyCal.

HireMe is going to use the browser to perform a GET, to send an authorization request to MyCal's authorization server.

The MyCal authorization server then prompts you to log in with MyCal, if you're not already logged in.

You're going to authenticate with MyCal.

And then the MyCal authorization server's going to prompt you in the browser for your consent to allow HireMe to access the MyCal APIs to add an event on your behalf to your calendar.

But not do any more than that.

If you agree, then the MyCal authorization server sends an authorization code to HireMe in the browser and HireMe takes that code and its own applicant credentials, and it returns those to the authorization server using Server Side.

MyCal can then issue a token, which HireMe can use to call the MyCal API within the scope of permissions that were accepted by you, the user.

So now HireMe, can set calendar events for you using the MyCal API on your behalf.

And nothing insidious is happening now.

MyCal is asking you to log in with MyCal.

HireMe is not asking for your MyCal credentials.

HireMe can now only create events, but not do other things like read all of your events or change your settings.

And we have the issues with sharing credentials and providing too much access, basically resolved and no longer a problem.

Only the thing that happened was that apps wanted to do more than call APIs.

Once they had access to this OAuth system, they really wanted to be able to sign users in with accounts that lived in other systems.

So for example, if we apply this to our hypothetical, then maybe HireMe wants a MyCal user to be able to log into HireMe using their MyCal account, despite not having a HireMe account.

Now OAuth 2 is for delegated access.

It's not an authentication protocol.

That means that if HireMe, does something like use that access token for the MyCal API and assume that having that access token and calling the API with it means that the user can be considered authenticated with HireMe, then we start running into problems.

Those problems include things like someone could have stolen the token, the token could be from a completely different user.

The token could be obtained from another client that's not HireMe and then just injected into HireMe.

And we call this the confused deputy problem, because HireMe doesn't actually know where this token came from or who it was issued for.

And if you remember, when we talked about authentication, authentication is about verifying the user is who they say they are.

And HireMe, can't know this from using this access token.

So to address this, we needed to formalize authentication on top of OAuth.

This leads us to the rise of openID Connect or OIDC.

Now OAuth 2 specialized in delegated authorization and openID connect covers authentication, specifically OIDC's and identity layer on top of OAuth 2, for authenticating users using an authorization server.

So let's talk a little bit more about that authorization server.

We know that it has a function to issue tokens.

So for authentication with OIDC, we use something called ID tokens.

In this scenario, our authorization server can issue ID tokens similarly to the way that it issues access tokens.

But ID tokens are meant for the client and they're a fixed format that clients can parse and validate.

They do this in order to extract identity information from the token.

And therefore they can know who the user is.

They can authenticate the user.

OIDC extends OAuth 2.0, to show how to issue ID tokens.

The OIDC spec also declares a fixed format for ID tokens, and this format is JSON Web Token.

So JSON Web Tokens.

often abbreviated JWT, which is pronounced jot, oddly enough, look like this.

There are three strings segments concatenated with periods.

The first segment is adjacent object containing a signing algorithm and the token type, which is JWT.

This is then base64 URL encoded so that it's safe for URLs and file names.

And the second segment is a payload segment.

These are data claims.

This is a JSON object that contains statements about the user and also statements about the authentication event itself.

This is also base 64 URL encoded.

And finally we have the crypto segment or the signature.

JSON Web Tokens are signed so that they can't be modified in transit.

So when an authorization server issues an ID token, it signs it using a key.

And then when the client receives that ID token, it validates that signature using a key as well.

And if we use an asymmetric signing algorithm, then different keys are used to sign and to validate the tokens.

And if this is the case, then only the authorization server holds the ability to sign tokens.

That's done with a private key and then a public key is available to clients that want to validate tokens.

As per their moniker, ID tokens provide identity information.

So in that payload segment, those data claims, we have that JSON object with things like statements about the end user and also information about the authentication event itself.

Those authentication claims can look something like this.

We might have an issuer.

This is your authorization server.

It's the party that issued the token in the first place.

We might have an audience.

This is the ID of the applications the token has been issued for-it's the intended recipient of the token.

We have some timestamps.

These tell us when the token expires and when it was issued.

And then we have something called a 'nonce', and this is important.

This is a cryptographically random string that binds the client to the ID token that it receives.

This nonce is present in both the authorization request and in as a claim that the authorization server inserts into the token that it sends back to the client.

So the client application then receives this token, it decodes it, and it needs to check to verify that the nonce and the token matches the nonce that it sent with its authorization request to the authorization server, because if they don't match, then the token should be rejected.

This is done in order to prevent something called token injection, which is tokens coming from somewhere other than the authorization server.

So in addition to validating the signature, the client also needs to do things like verify that the authentication claims like the issuer, the audience, the timestamps, and the nonces.

And as I mentioned, claims also contain statements about the end user.

Some of the standard claims that we can ask the authorization server to provide are things like profile information.

We have a subject, this is a unique user identifier.

We can get profile claims like address, nickname, maybe an avatar, website, email, all kinds of information.

So I talked about access tokens very briefly when we introduced OAuth 2, but now I want to come back to them because now we've covered ID tokens, let's say the user is authenticated.

So now we're ready to call a resource API.

So we're ready to cover access tokens in a little bit more depth.

As I said before, access tokens are for accessing resources.

For example, granting access to the MyCal API and unlike ID tokens, which are JSON Web Tokens, as per the specification, access tokens have no specific defined format.

They don't have to be, and are not necessarily JSON Web Tokens.

However many authorization servers do use the JSON Web Token format for access tokens as well.

These include services like Auth0, Amazon Cognito, Microsoft identity server, Okta, and others.

And they do this because the format, the JWT format enables validation.

Access tokens are for the resource API, they're intended for the API.

And unlike ID tokens, access tokens are opaque to the client.

The content in an access token can change at any time, And the client should never contain code that relies on what's in the access token content.

What does API access with an access token look like?

Well, let's say our user is logged into our client application and we have our authorization server and we request an access token to get resources from an API.

So when we go to call the API from the client, in order to request data and resources, we attach the access token to that request.

We send the request to the API and then the API validates the token using middleware.

If everything checks out.

Then the API returns the requested data to the application.

But how does the API know what access it should give the app when it's asked for those resources?

Well, we do this through delegation with scopes.

Remember this?

We only want HireMe to create calendar events using the MyCal API.

We don't want it to be able to do more than that.

Scopes basically limit what an application can do on the behalf of the user.

Scopes can't grant privileges that the user doesn't already have.

So if your, MyCal user doesn't have a privilege to set up new MyCal enterprise accounts, for example, then scopes granted to HireMe, won't ever allow the user to set up new enterprise accounts either.

Scopes delegate access control to the API or the resource.

The API is then responsible for combining those incoming scopes with known actual user privileges, and then it's going to make the appropriate access control decisions.

This is sort of where delegated authorization comes from.

So in practice, we have our user using our application and they're going to access a third party MyCal API.

And let's say we've already acquired an access token from our authorization server.

The token that's received from the authorization server already contains information like the user identifier, the subject, it contains the audience saying that the token is intended to be used by the MyCal API.

And maybe it contains a scope that says it has permission to write calendar events.

We then send that request with the token to the API.

And we have this scope with this 'write events', permission, but the API has the ability to access everyone's calendars.

It can access the calendars of the hundreds of thousands, maybe millions of users.

So in addition to looking at the token's scope, the resource API really needs to use the subject identifier in order to only allow this user to exercise their own capabilities and not access, for example, other user's calendars by accident.

So in the context of delegated authorizations, scopes express what an application can do on the user's behalf.

Scopes are a subset of the users capabilities.

Now remember when we prompted the user for consent for MyCal to allow HireMe to do certain things?

Well, more realistically, that consent dialogue might look something like this.

HireMe could potentially ask for a variety of different scopes, but you shouldn't overload scopes with user specific permissions.

Scopes are really intended for app level permissions.

So what have we learned?

We've taken the concept of going from a vague idea to a fully finished solution, and we filled in a lot of the concepts behind things like OAuth2, openID Connect, authorization servers, iD tokens and JSON Web Token format.

We covered access tokens, scopes, and delegated authorization.

And I encourage you to stay tuned for the next talk at Safe, which is going to discuss how to take these specifications and apply the concepts and implement authorization authentication in your applications.

So I hope that this talk has demystified some of the crucial background around the standards and the basics of authorization and authentication.

Once again, my name is Kim Maida.

I am a Google developer expert in security, privacy payments, and identity.

I'm an Auth0 ambassador and I'm also the former head of developer relations at Auth0.

And I'm currently the vice president of DevRel at Ionic.

I wrote a pretty in-depth blog article, that's linked here, and you can find all of this content as well as links to a lot more resources on these topics there.

I really enjoy connecting with people on Twitter, and I really appreciate you joining me today.

So thank you very much.

THE ART OF AUTHENTICATION & AUTHORIZATION

@KimMaida

Tweet from @nick_craver with a photo of a young boy jumping on a bed. Text reads "1. 'Are you ready to work on the auth code?' 2. New dev: 'Hell yeah, bring it on!' 3. [no reply]"

How to add authentication:

How to add authentication:

  • 1. Search for "auth"

image of the start of the steps in drawing an Owl, from the "How To Draw an Owl" meme, where the first step is two simple ovals and the second step is an intricate line drawing.

How to add authentication:

  • 1. Search for "auth"
  • 2. Do the rest of the auth stuff

image of the complete how to draw an owl meme.

How to add authentication:

1. Search for "auth"

"Do the rest of the auth stuff" is struck out and replaced with "Use an identity service".

Image of a 7 step process in drawing an owl

INTRO TO STANDARDS

IDENTITY

DIGITAL IDENTITY

DIGITAL IDENTITY

The set of attributes that define an individual user in an application

AUTHENTICATION

AUTHENTICATION

Process of verifying the user is who they say they are

AUTHORIZATION

AUTHORIZATION

Rights to access resources

OAUTH 2.0

BEFORE OAUTH...

History Lesson: Before Delegated Authorization

Icon representing the HireMe123 App. Below to the right is an icon representing user

Icon representing the HireMe123 App. Below to the right is an icon representing user. To the right again is an icon representing the MyCalApp

History Lesson: Before Delegated Authorization

Diagram representing the HireMe123 App delegating authorization to the MyCalApp user.

History Lesson: Before Delegated Authorization

Diagram representing the HireMe123 App delegating authorization to the MyCalApp user.

History Lesson: Before Delegated Authorization

Diagram representing the HireMe123 App now having direct authorization to MyCalApp for the user..

History Lesson: Before Delegated Authorization

Diagram representing a calendar being shared from the MyCalApp to HireMe123 for the user.

Sharing Credentials is Bad

😱

ENTER OAUTH

OAUTH 2.0

Open standard for performing delegated authorization

https://tools.ietf.org/html/rfc6749

OAUTH 2.0

Grant third party access to APIs without exposing credentials

https://tools.ietf.org/html/rfc6749

AUTHORIZATION SERVER

AUTHORIZATION SERVER

Set of endpoints to interact SERVER with user and issue tokens

OAuth 2.0: Delegated Authorization with Authorization Server

repeat of diagram of HireMe123 and MyCalApp and user icon

OAuth 2.0: Delegated Authorization with Authorization Server

repeat of diagram of HireMe123 and MyCalApp and user icon. MyCalApp now has an icon representing that it is a Authorization Server.

OAuth 2.0: Delegated Authorization with Authorization Server

Repeat of this diagram with an icon representing the user logged into HireMe123

Repeat of this diagram with a dotted line representing the HoreMe123 App connecting with MyCalApp to authorise the user.

Repeat of this diagram with a dotted line connecting the user and MyCalApp, representing step one of the user logging in and authorizing HireMe122

MyCalApp

OAuth 2.0: Delegated Authorization with Authorization Server

Repeat of this diagram with a dotted line connecting the user and MyCalApp, representing step two of the user logging in and authorizing HireMe122

OAuth 2.0: Delegated Authorization with Authorization Server

Repeat of this diagram with a dotted line connecting the user and MyCalApp, representing step three of the user logging in and authorizing HireMe122

OAuth 2.0: Delegated Authorization with Authorization Server

Repeat of this diagram with a dotted line connecting the user and MyCalApp, representing step four of the user logging in and authorizing HireMe122

OAuth 2.0: Delegated Authorization with Authorization Server

Repeat of the diagram with a dotted line connecting the two apps, representing the authorisation server connecting with the HireMe123 app, asking for the user's authorisation details

OAuth 2.0: Delegated Authorization with Authorization Server

Repeat of the diagram with a dotted line connecting the two apps, representing the HireMe123 app sending the user's authorisation details to the authorisation server.

OAuth 2.0: Delegated Authorization with Authorization Server

repeat of diagram of HireMe123 and MyCalApp and user icon, showing the user is logged in and authenticated in the HireMe!23 app

OAuth 2.0: Delegated Authorization with Authorization Server

repeat of diagram of the MyCalApp sharing an authorised version of a calendar with HireMe123.

No more credential sharing

No problems with too much access

🙂

Apps wanted to do more than call APIs

🤔

WANTED

To sign in users with accounts living in other systems

Apps Wanted to Log Users In

repeat of diagram of HireMe123 and MyCalApp and user icon

With Accounts From Other Systems

repeat of diagram of HireMe123 and MyCalApp and user icon. The MyCalApp has an icon representing the user logged in with a calendar

With Accounts From Other Systems

repeat of diagram of HireMe123 and MyCalApp and user icon. The HireMe123 has an icon representing the user logged in with a calendar

OAUTH 2.0

For delegated access; Not an authentication protocol

Problems with Access Tokens for Authentication

repeat of diagram of HireMe123 and MyCalApp and user icon, showing the user is logged in and authenticated in the HireMe!23 app.and a calendar is being shared with it from MyCalApp. A red arrow points to the authenticated icon of the HireMe123 App

Problems with Access Tokens for Authentication

repeat of diagram of HireMe123 and MyCalApp and user icon, showing the user is logged in and authenticated in the HireMe!23 app.and a calendar is being shared with it from MyCalApp. A large question mark is below the authenticated icon of the HireMe123 App

Confused Deputy Problem

repeat of diagram of HireMe123 and MyCalApp and user icon, showing the user is logged in and authenticated in the HireMe!23 app.and a calendar is being shared with it from MyCalApp. An emoji of a female police officer with question marks above their head is below the authenticated icon of the HireMe123 App

To formalize authentication on top of OAuth:

🧐

OPENID CONNECT

OAUTH 2.0 Delegated Authorization

OPENID CONNECT Authentication

OPENID CONNECT

Identity layer on top of OAuth 2.0 for authenticating users with an Authorization Server

https://openid.net/specs

Authorization Server

Authorization Server Issues Tokens

ID TOKENS

Authorization Server Can Issue ID Tokens

ID TOKENS

Authorization Server Can Issue ID Tokens

ID TOKENS

ID Tokens Are For The Client

ID TOKENS

ID Tokens Are Fixed Format

ID TOKENS

ID Tokens Identify the User

ID TOKENS

OPENID CONNECT

Extends OAuth 2.0 to show how to issue ID tokens

ID TOKENS

Fixed format

https://tools.ietf.org/html/rfc7519
 https://jwt.io

JSON WEB TOKEN

JSON Web Token (JWT / "jot")

Header Segment - Algorithm & Token Type

{
	"alg": "RS256", "typ": "JWT"
}

Payload Segment - Data Claims

{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022 }

Crypto Segment - Signature

Signature

Crypto Segment - Signature

icon representing a digital signature

Client Validates JWT Signature

Token is repeated. Magnifying glass inspecting an old fashioned key zooms in on a small part of the signature block.

ID TOKENS PROVIDE IDENTITY INFO

openid.net/specs/openid-connect-core-1_0.html#Claims

Payload Segment - Data Claims

data claims slide is repeated, drawing attention to the section below

{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022 }

CLAIMS

Statements about End User and Authentication event

openid.net/specs/openid-connect-core-1_0.html#Claims

ID Token Authentication Claims

iss: "https://you.authz-server.com"

aud: "RxHBtq2HL6biPljKRLNByqehlKhN1nCx"
 exp: 1570019636365

iat: 1570016110289

nonce: "3yAjXLPq8EPP0S"
 
...etc

ID Token Authentication Claims

iss: "https://you.authz-server.com"

aud: "RxHBtq2HL6biPljKRLNByqehlKhN1nCx"
 exp: 1570019636365

iat: 1570016110289

nonce: "3yAjXLPq8EPP0S"

...etc

ID Token Authentication Claims

The code block above is repeated with attention drawn to the following line, and a note reads "Issuer your authorization server"

iss: "https://you.authz-server.com"


ID Token Authentication Claims

The code block above is repeated with attention drawn to the following line, and a note reads "Audience Client ID"

aud: "RxHBtq2HL6biPljKRLNByqehlKhN1nCx"


ID Token Authentication Claims

The code block above is repeated with attention drawn to the following lines, and a note reads "Expiration Issued At Timestamps"

exp: 1570019636365

iat: 1570016110289


ID Token Authentication Claims

The code block above is repeated with attention drawn to the following line, and a note reads "Nonce binds client to token"

nonce: "3yAjXLPq8EPP0S"

VALIDATE JWT

Verify authentication claims

CLAIMS

Statements about End User and Authentication event

openid.net/specs/openid-connect-core-1_0.html#Claims

ID Token User Claims

sub: "google-oauth2|102582972157289381734"
 
name: "Kim Maida"

picture: "https://gravatar[...]"

website: "https://github.com/kmaida/about"
 
email: "kim.maida@auth0.com"

...etc

ID Token User Claims

sub: "google-oauth2|102582972157289381734"
 
name: "Kim Maida"

picture: "https://gravatar[...]"

website: "https://github.com/kmaida/about"
 
email: "kim.maida@auth0.com"

...etc

https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

ID Token User Claims

The code block above is repeated with attention drawn to the following line, and a note reads "Subject user identifier"

sub: "google-oauth2|102582972157289381734"
 

https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

ID Token User Claims

sub: "google-oauth2|102582972157289381734"
 
name: "Kim Maida"

picture: "https://gravatar[...]"

website: "https://github.com/kmaida/about"
 
email: "kim.maida@auth0.com"

...etc

https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

ACCESS TOKENS

ACCESS TOKENS

Accessing resources

ACCESS TOKENS

No specific format

ACCESS TOKENS

Aren't necessarily JWT

ACCESS TOKENS

Aren't necessarily used by many authorization servers

Access Tokens are opaque to client

🙈

Resource Access with Access Tokens

On the left an icon representing an authorized user. On the right, an Authorisation server. A sequence of slides represents the authorisation process Kim describes

DELEGATION WITH SCOPES

OAuth 2.0: Delegated Authorization with Authorization Server

repeat of diagram of the MyCalApp sharing an authorised version of a calendar with HireMe123.

SCOPES

"Scopes limit what an app can do on the behalf of a user"

https://auth0.com/blog/on-the-nature-of-oauth2-scopes

SCOPES

Cannot grant privileges the user doesn't already have

SCOPES

API is responsible for calculating permissions

Delegation with Scopes

A series of slides represent the process of delegating with scopes that Kim describes in detail.

SCOPES

Express what an application can do on the user's behalf

SCOPES

Subset of user's capabilities

Subset of user's capabilities

Diagram of user logging into MtCalApp as an authorisation server.

Subset of user's capabilities

Icon representing the authorised user

Subset of user's capabilities

Dialog asking to Athorize the App for Kim. message reads "Hi Kim Maida, HireMe123 is requesting access to your MyCalApp account." Below is a calendar icon and the label "Calendar: write events". At the bottom are OK and Cancel buttons.

Subset of user's capabilities

The above dialog is repeated. A red arrows points to the following list

  • write:events
  • read:events
  • read:settings
  • write:settings
  • ...etc

What have we learned?

🦉

Repeat of the two owls in the How to draw an owl meme.

Repeat of the 7 owls in the how to draw an owl lesson. The first is labelled with the OAuth2 icon, the second the OpenID icon, the third the authentication server icon, the fourth the authenticated user icon, the fifth the access tokens icon, the sixth the delegate scope icon and the 7th icons representing the various authentication processes.

THE ART OF AUTHENTICATION & AUTHORIZATION

🖌

THE ART OF AUTHENTICATION & AUTHORIZATION

ionic.link/kmaida-auth

Kim Maida

Google Developer Expert Auth0 Ambassador

VP of Developer Relations

Chat with me on Twitter! (@KimMaida)