Full transcript
0:14All right. Good morning everybody.
0:16Thank you for coming to this talk.
0:18Hopefully your morning was eventful. I
0:21caught a little bit of the keynote. I
0:22wasn't able to catch all of it, but it
0:23was pretty good. Um, my name's Garrett
0:25Gallo. Today I'm going to be talking
0:27about one login to rule them all. Uh, or
0:30cross-app access for MCP in case you
0:32haven't heard about that.
0:34Uh, quick intro about myself. Uh, I run
0:37product at WorkOS. I've been building
0:39enterprise developer platforms for the
0:41past almost 15 years. Uh, originally at
0:43Microsoft Azure, then at Cloudflare for
0:45a long time, and now at WorkOS.
0:49If you haven't heard of WorkOS before,
0:52we make your app and also your agents
0:54enterprise ready.
0:55Uh, we power off for the likes of
0:57Anthropic, Cursor, OpenAI. So, if you
0:59ever logged into Cursor for example,
1:01whether that was with username password
1:03or like an enterprise IDP, you've used
1:05WorkOS.
1:07Um,
1:09today I'm going to be talking about, uh,
1:11MCP and sign in through things like
1:14Anthropic and Cursor.
1:15Um,
1:17but first, uh,
1:19if you've used MCP at all extensively,
1:21you know that it means consent screens
1:23on top of consent screens on top of
1:25consent screens. Who here uses MCP
1:26servers on the regular?
1:28Okay, most of you.
1:30Um, if you haven't kind of experienced
1:32this before,
1:33uh, here is, uh, Cursor which I have set
1:36up. Uh, and if you want to use MCP
1:38servers with Cursor, you know, you add
1:40them and you have the little config
1:41file, and then in each one of these, if
1:44you want to, use it, you have to
1:45connect.
1:46It'll pop up this window. You have this
1:48nice little consent screen that you're
1:49not going to read. You're just going to
1:51say okay.
1:52And you're going to get redirected back.
1:54And you need to do this for every single
1:57tool,
1:58which is frankly pretty annoying. And
2:01sometimes you have to do this again. You
2:02don't really know why sometimes you have
2:03to do this again. Sometimes it seems to
2:05forget that you've already done this.
2:07Um,
2:08yeah, and so this is like a thing you
2:09have to do,
2:11uh,
2:12every time you want to use, uh, these
2:14MCP servers.
2:15And, uh, that's not fun. But it's in a
2:19company with a lot of developers, it's
2:20not just, you know, one person's
2:22inconvenience.
2:23Uh, as a user you might log into a half
2:25dozen or a dozen MCP servers.
2:27Um, but when you combine that together
2:29across your team, you basically have
2:32dozens and dozens of people spending all
2:33this time managing all these consent
2:35screens, clicking these buttons, uh,
2:37without really caring why they have to
2:38do this.
2:40Now, this is a relic of a lot of the
2:41technology that MCP decides to use. It
2:43uses OAuth as the underlying, uh,
2:45authentication layer. And so, uh, the
2:48way OAuth was kind of invented around
2:49was a thing of like, you don't trust,
2:50you know, these two systems don't trust
2:52each other, so you have to like provide
2:53this consent to say, yes, Cursor can
2:55have access to my Figma account. Yes,
2:57Cursor can have access to my Notion
2:58account.
2:59Um, the reality is
3:01that's not really how,
3:03uh, you know, things operate today.
3:05That's not how companies operate.
3:08Um, you know, we have a thing called
3:10single sign-on. Most people are using it
3:11if you have a company, you're logging in
3:13through something like an Okta or
3:14Microsoft Entra, one of these systems.
3:17Um, and that's sort of, you know, that
3:19idea of like one login, sign into all
3:21those applications, worked great. But
3:23MCP breaks this model, right? It sort of
3:25assumes that, uh, you know, none of
3:27these apps know anything about each
3:29other. There's no way to know that
3:30you're the same person, that, you know,
3:32you should have access to these systems.
3:33So, you have to go through these flows
3:35over and over and over and over again.
3:38Now, that is really annoying.
3:40Um, and maybe that unto itself is a
3:41problem worth solving, but, you know,
3:43humans will tolerate a lot of annoyances
3:45if they get value out of it.
3:47The real problem comes in,
3:49um, for the IT team. Like the people
3:52managing all these applications,
3:54uh, MCP's not doesn't work the way that
3:56they want it to work.
3:59You know, IT can't really tell like what
4:01MCP service you may or may not be using.
4:03You're connecting to these arbitrary
4:04things. You're not necessarily going
4:07through that IDP to connect to them,
4:09um, which is problematic.
4:11They basically can't determine, uh, you
4:13know, which AI agents you can actually
4:15use, right? Uh, in theory, you can take
4:18any arbitrary MCP client, you know, that
4:20might be a Cursor, but you could be
4:21using, um, sort of like a DeepSeek or
4:24some of these other tools that maybe
4:26your IT team doesn't want you to use.
4:28And, um, you're going to get access to
4:30these sensitive systems, right? You
4:31know, you have lots of data in things
4:33like Figma or Notion that, you know, IT
4:36maybe doesn't want any, you know, any AI
4:38agent to get access to.
4:41The other thing is actual access and
4:42security. Um, I don't know how many
4:45people heard about the NPM Axios package
4:48getting popped about a week ago. Uh,
4:51unfortunately, I was, uh, hit by that.
4:53I'm still not exactly sure what NPM
4:56package thing I used that had that
4:57dependency, but, uh, you know, our IT
5:00team, you know, became aware of that
5:02problem. They were able to detect that,
5:04you know, my machine had been
5:05compromised. They were able to cut off
5:07network access to my machine. They could
5:09invalidate my Okta sessions across all
5:11the applications, so they could help
5:12secure,
5:13uh, you know, my my account and our
5:15company data.
5:17But, you know, in my local machine, I
5:19had MCP servers connected. I had like
5:21API keys that I was using for certain
5:22things. Like that's the real we had to
5:24go through and do all this, you know, I
5:25was looking through my laptop saying
5:26like, what am I connected to? What
5:28services might I have some sort of other
5:31credential not driven from the IDP that,
5:33you know, is at risk of being leaked?
5:35How do we go revoke that? How do we
5:36ensure that, you know, my system's safe?
5:40Uh,
5:41MCP today using OAuth, you know, if
5:43something happens like that or, you
5:45know, you leave a company, and IT might
5:47revoke your, you know, single sign-on
5:49through your IDP to those applications,
5:51you still have these access tokens,
5:52these refresh tokens even in most cases
5:54that give you standing access to these
5:56services. That means you might have
5:57access for, uh, days or weeks or even
6:00months.
6:01Um, you know, many companies don't use
6:03things like SCIM, which allows you to
6:04revoke that access fully, but, you know,
6:06and so that means that,
6:09uh, you have this like lasting access
6:11problem that IT doesn't have any
6:12visibility over.
6:14And then, again, every time someone's
6:15onboarding to the team, they have to go
6:17through this whole thing where, uh, IT
6:19might be able to like automatically set
6:20up the MCP servers you're using in
6:22something like Cursor or Claude,
6:24um, but you still need to go through all
6:25this authentication, um, and manage all
6:28these connections yourself.
6:30So,
6:31um, obviously this isn't great. So, what
6:33are we doing about it? All right, what's
6:34the solution to this?
6:37The solution is cross-app access,
6:39otherwise known as XAA.
6:43XAA is basically a way in which the
6:45identity provider can act as a stand-in,
6:47a trust provider between applications.
6:49So,
6:51let's say the example of I have Cursor.
6:53That's my MCP client.
6:55Uh, Figma's the MCP server I want to
6:56connect to.
6:58And then Okta's the IDP that we use at
7:00our company for logging into things.
7:03So, both Cursor and Figma already have
7:06this trust relationship with
7:08Okta, right? To get logged into Cursor,
7:10I go through Okta. To log into Figma, I
7:12go through Okta. So, both of these
7:13applications know about, you know,
7:15workos.okta.com.
7:17They know about me as a person that has
7:18access to these applications.
7:21What cross-app access does, it helps
7:22bridge the gap between Cursor and Figma
7:24by providing a way for Cursor to talk to
7:26Figma. They can both depend on that
7:29trust reliance on Okta, and they can get
7:31credentials issued without manual or
7:33human intervention.
7:36So, let me show you a little bit what
7:37that looks like. So, I'm going to flip
7:39over to,
7:41uh, my terminal and make it
7:43bigger and more visible.
7:45So,
7:46uh, here on the left on this tab, I have
7:49just like regular Claude code set up,
7:51and, you know, if I check my MCP
7:53servers,
7:54uh, you know, I've connected the Figma
7:56server here. Obviously it needs
7:57authentication. I could go through that.
8:00You know, it's going to present a
8:00consent screen.
8:02Um, that's kind of the standard flow.
8:05Uh, in this window over here, uh, we
8:08have a version of Claude code that is
8:10XAA compatible. Basically implemented
8:12XAA here. So, um, the first thing I do
8:14just kind of show,
8:16uh,
8:17since this is sort of like a a beta
8:18implementation of this,
8:22um, I can basically say like I have
8:24configured inside of Claude code, um,
8:27this connection to my Okta environment.
8:29And the first thing I'm going to do
8:32here is
8:37I'm going to log in.
8:40And so this is doing an Okta login. I'm
8:43going to log into my Okta environment.
8:44You know, this is a thing you need to do
8:45one time in order to, uh, if you were,
8:49you know, setting up Claude for the
8:50first time, you'd be logging into Okta.
8:52Okay, that's all done now.
8:56Um, and then now if I start up Claude,
8:59and I look at my MCP servers,
9:02we'll notice here that Figma is
9:04automatically connected. Let me try and
9:05make that a little bit bigger.
9:08And so, I didn't have to do, I didn't
9:10have to click anything. I didn't have to
9:12see a consent screen. Uh, Figma's
9:14automatically connected, and now, you
9:16know, whether it's Figma or a list of
9:17MCP servers, I can do all of that.
9:20I know that kind of seems like magic. I
9:22didn't actually have to click anything.
9:23Did I actually do anything? Promise I
9:25did. Let me kind of talk a little bit
9:26about what's actually happening behind
9:27the scenes. The whole point of this is
9:29you don't have to do anything, right?
9:30So, it doesn't, it appears as like it's
9:32sort of automatic.
9:34But, uh, here's how it works. So, in
9:36this, uh, situation, we basically have
9:38four systems. The client, which in that
9:40case was Claude code I was using.
9:43The identity provider, which is Okta.
9:45The resource authorization server, uh,
9:47which is in this case managed by Figma,
9:49but we're separating it from the
9:51resource server, which is the Figma API.
9:53Um, if you're not familiar in MCP,
9:55you'll have the resource server, which
9:56is like your MCP server. It will call
9:58out to a separate place to do
9:59authorization and issue tokens.
10:02So, in the case the first thing I did, I
10:04did that Octa login, right? So, the user
10:06goes through SSO to the IDP.
10:09And that issues back an ID token and
10:11refresh token. So, in this case Claude
10:13holds onto those tokens. And it's able
10:16to use that in the next step to
10:18uh
10:20to ask for what's called a ID Jag token.
10:23So, ID Jag is uh happens to be the name
10:26of the spec that that all this
10:28technology is built off of. Stands for
10:30identity JWT authorization grant. It's
10:33very
10:34big mouthful.
10:35Effectively, it just means a token
10:37issued by an IDP that can be used across
10:40services to uh manage access.
10:43So, the client goes back to the IDP and
10:45says, "Hey, I have this refresh token
10:47for Garrett. Would you please give me
10:48this ID Jag token that will work with
10:51Figma?"
10:52Uh Octa basically knows about Claude,
10:55knows about Figma. It can check, "Hey,
10:57is Garrett a member of both of these
10:58applications?
11:00Uh am I allowed to do this? Is am I
11:02allowed to issue tokens for Claude on
11:04behalf of Figma?"
11:05The answer is yes. Octa will send back
11:07this ID Jag token to Claude code.
11:10Then Claude sends that to Figma, in this
11:13case Figma's authorization server. Says,
11:15"Hey, I have this ID Jag token for
11:16Garrett from the WorkOS Octa instance.
11:19Could you please validate this and
11:21provide me back a token?"
11:24Figma, because it has this relationship
11:25with Octa, goes through, verifies the ID
11:28Jag. Once that's verified and correct,
11:31it is then able to issue this access
11:33token back to Claude code. And at that
11:35point, uh step four here is the regular
11:37MCP off flow. So, it just starts talking
11:39to the MCP server. It's using a regular
11:43OAuth access token. It's not a new type
11:44of credential.
11:46And then, you know, now I can talk to
11:47the MCP server. Figma will issue
11:49responses, and we're off to the races.
11:51Uh a few things that are important here.
11:54Uh steps two and three here are totally
11:56invisible to the user, right? Once I've
11:58logged into the IDP, which I don't have
12:00to do that very often, you know, that
12:02could be, you know, once a day. It's
12:04kind of up to the IT, you know, your
12:06company's policies. Maybe that's once
12:07today, maybe that's once a week. Once
12:09you've done that login, you don't have
12:10to do that again.
12:12Steps two and three are done behind the
12:13scenes.
12:14Uh and then step four is just the
12:16regular access token request that you're
12:17doing to the MCP server.
12:20The other thing around this is
12:22uh in the case of this access token
12:23that's being issued,
12:25uh that could be very short-lived. So,
12:28most applications issue access tokens
12:30around 5 minutes.
12:32Um and so, what happens is that token
12:34will expire after 5 minutes, but
12:37you don't need the human to do anything.
12:38You can basically rerun this ID Jag flow
12:41plus the exchange and get a new access
12:43token as needed. And so, as long as your
12:45SSO session is active, you can keep
12:47getting these ID Jag tokens, exchanging
12:49them for access tokens. And so, you
12:50actually have a better security posture
12:52where if something happens and, you
12:54know, my access is removed for some
12:56reason or my session is locked with
12:58Octa, once that access token expires, I
13:00won't be able to get back in. I won't be
13:02able to reconnect to that MCP server.
13:06And so, I want to go a little bit
13:07through um, you know, what does this
13:09look like on the setup side? Like, what
13:10does your IT admin need to do? If you're
13:13running an MCP client, what do you need
13:14to do? If you're running an MCP server,
13:15what do you need to do?
13:17On the IT side, it's actually pretty
13:18straightforward, right? Uh you're
13:20already going to have a like Claude code
13:23or Cursor Octa application created.
13:25You're already going to have the Figma
13:26SSO application created, right? Those
13:27will be existing things that your
13:29company already has.
13:30Inside of a system like Octa, there's
13:32this new kind of managed connections
13:33portal.
13:34Where you basically come in and say,
13:36"Hey, which app do I want to grant the
13:38ability to request access to this other
13:40app?" So, in this case, uh we're saying
13:42Cursor can request access to Figma.
13:45Uh and that policy means that when if
13:47Cursor comes knocking and says, "Hey
13:49Octa, can I have an ID Jag token for
13:52Figma?" part of its request is which
13:54system is the one I want access to.
13:56Octa can verify that and say, "Yes,
13:58actually
13:59uh Cursor is allowed to request this
14:01access out of Figma."
14:02And we'll issue that token. So, that's
14:04all all you really have to do on the IT
14:06side. Once you've done that, everything
14:08else is as normal, like, you know, the
14:09user must belong to both applications.
14:11You're kind of doing the same kind of
14:12management policy as you normally do.
14:16On the MCP client, so this would be your
14:18Claude code, your Cursor, or if you're
14:20building kind of your own MCP client,
14:23there's a handful of things you need to
14:24do.
14:25One, you need to have an SSO connection
14:27that's XAA compatible. So, you know, in
14:29general, if you're supporting SSO in
14:30your application or your client, that's
14:32kind of the standard fare.
14:34Um XA support is relatively new, so uh
14:37Octa does support it, but with some
14:39caveats.
14:40Um they're working through those. We're
14:42working with other industry partners
14:43like Microsoft so that have them support
14:45this as well.
14:46But you need that, and that customer's
14:48uh IDP connection will need to be XAA
14:50compatible enabled.
14:52Uh your client requests this ID Jag
14:54token from the ID uh identity provider.
14:56You get that token back. You need to
14:58make that exchange request to the MCP
15:00server, so you need to uh support uh
15:02that token flow. And then, once that's
15:04done, number four is your standard just
15:07talk to an MCP server. So, nothing new
15:09there.
15:10Uh we've built support as someone who,
15:12you know, we provide authentication
15:13services for for our customers, we've
15:15built support for one, two, and three
15:17here. So, we can handle, if you're
15:18building an MCP client, we can handle
15:19all of that flow.
15:21Um we're actually the way in which, you
15:22know, Cursor and Anthropic are doing
15:24this because they use us for their SSO
15:26connections.
15:29On the MCP server side, which is
15:31probably more relevant to most folks is
15:32like you might be, you know, your
15:34company might have an MCP server you
15:36want your customers to use. There's also
15:37some stuff you need to do to support it
15:39on your side.
15:41The first is there's this new um JWT
15:44bearer type that you need to support. Um
15:46so, this is basically like announcing
15:47that you now support uh this ID Jag flow
15:50and that you'll accept these kinds of
15:51tokens.
15:52Then obviously like MCP clients are
15:54going to send you those tokens. You need
15:55to accept them.
15:57Uh
15:57and then you need to verify them. So,
15:58there's a step where you go to the uh
16:01identity provider the Octa URL and say
16:03like, "Hey, is this a valid token?" It's
16:04basically this kind of a signed JWT.
16:06Kind of like how you'd validate a JWT in
16:08any other context, you're doing the same
16:10thing here.
16:11And then last, uh which should be kind
16:13of the normal thing, is issue the access
16:15token, right? So, you validated
16:16everything. Now you want to give them an
16:19access token.
16:22If you'd like to learn more about how
16:23this works, I, you know, kind of treated
16:25this as like a high-level overview.
16:27Obviously, like there's a whole spec
16:28defining ID Jag and the specifics around
16:30how it should work. Uh that's an
16:32exercise I leave to you, the reader, if
16:34you want to go explore the spec. Um I
16:36will say like Claude is very good at
16:38explaining the spec, so that might be an
16:39easier way to get introduced to it
16:41without having to go read, you know, uh
16:43IETF nomenclature. Um
16:45but here we have a blog post kind of
16:47outlining all the details around ID Jag,
16:48how does it work, um a lot more of the
16:50technical aspects of it if you're
16:52interested. Um so, yeah, you can check
16:54that out to learn more.
16:56And with that, uh happy to answer any
16:57questions people have.
16:59Yeah.
17:00Um
17:01so, this might
17:03uh this might solve the authentication
17:05problem, but does it also solve the
17:06authorization problem? Let's say for
17:08Figma, you've got like different token
17:10scopes. Does that also solve the
17:12authorization bit as well? Yeah. Uh so,
17:15just so you know, I'm going to repeat
17:16questions so people on the recording can
17:17hear it. Question is this solves
17:18authentication, not authorization. Does
17:20this do anything to to help with that?
17:22Um by default, no.
17:25Uh so, this is pure kind of just around
17:27the authentication bit. Um this is
17:29still, you know, you're logging into
17:30Figma
17:31as yourself, you know, so you're getting
17:33the permissions that you have uh with
17:35Figma. Um one of the things we're kind
17:37of talking about is like, okay, how do
17:38you extend this to be able to um define
17:40like scoped access. So, maybe
17:43uh you know, Octa's saying, "Yes, I'm I
17:45will grant this crop cross-app access,
17:47but there's caveats alongside like the
17:50permissions I'm going to grant." That's
17:51not something that's like part of the
17:52spec today. Um but obviously like
17:54something that's important that we need
17:55to consider.
17:56Thank you.
17:58Uh
17:59It's the same question, but a second
18:00part to it. Yeah. Um how does the
18:04uh MCP client know which app to go for
18:08inside Octa?
18:11The question how does the MCP client
18:13know the app it's requesting access for
18:15in Octa? Uh the answer is based like an
18:18audience URL. So, you would use um in
18:21this case it's like, you know,
18:22mcp.figma.com.
18:24You know, it's the the
18:26uh Figma's MCP server.
18:28That audience will be known inside of
18:30Octa. And so, uh your Cursor will
18:33request to your Octa instance and say,
18:35"Hey, here's the audience I'm looking
18:36for."
18:37Um that's configured inside of Octa to
18:39say like the Figma app covers this
18:41audience.
18:43And then, that's how it's checking the
18:45access request. So, What's to prevent
18:46you from using that to hack scopes?
18:49Um no, I don't think you could use it to
18:51hack scopes cuz it's it's just audience,
18:53which is kind of like a standard OAuth
18:56parlance. So, um
18:58yeah, that's the thing that like uh
19:00Cursor knows the audience that it's
19:02trying to get based on the MCP server.
19:03Octa is configured to know for this app,
19:05that's the audience that it controls.
19:07And then obviously, you know, Figma
19:09knows its own audience and is and is
19:10checking uh you know, the validity of
19:12the JWT with with Octa.
19:17Cool.
19:18Yeah. Do you support uh Azure?
19:23Um Intra. Yeah, yeah. Is Intra
19:25supported? Uh
19:27Microsoft doesn't hasn't yet added XAA
19:29support inside of Intra. Um
19:33that's something we're working with them
19:34on. If you have connections, push uh cuz
19:37we want to get this adopted more
19:38broadly. Um yeah, I kind of more
19:41generally uh
19:42today with Octa, this is supported for
19:44OIDC based connections. Um but they're
19:47they're going to support this for SAML
19:48based connections as well. Um kind of
19:50the spec defines that you
19:53whatever you send to the IDP, it's
19:54either a refresh token, ID token, or a
19:56SAML assertion. So, kind of just
19:58something that proves that you have an
20:00you know, the user has a session in your
20:01app. Um, that's the only part that's
20:04cares about the type of SSO connection
20:06you have. But yeah, right now it's just
20:07Okta. Hopefully, that will be more soon.
20:09Okay, so so there is no intro at the
20:12moment. No, they don't support it yet.
20:14So,
20:15can I follow up with Sure. So,
20:18with Microsoft
20:20I ran into various
20:23client protocol fragmentation. Okay. Uh,
20:26there was a resource parameter problem
20:28where Cloud Code sends the resource. Uh,
20:31Entra validates, but it has to match the
20:33scope.
20:35Um,
20:36the way
20:37Codex does it is completely different.
20:39The way Cloud Desktop does it is not the
20:42same either. Sorry, this is to
20:46what part of the flow is this or what
20:49when Cursor or Cloud is talking to
20:52uh, Microsoft here, is that for like
20:54single sign-on or is that for talk
20:56>> Single sign-on. Okay.
20:59So, there's an RFC 9728.
21:03What what what does the initial
21:04discovery?
21:05Yeah. Uh,
21:07the resource and the resource and the
21:09scope have to match, otherwise Entra
21:11rejects it.
21:14Yes.
21:16And different protocols have need a set
21:18of different
21:20Yeah, I would have to maybe maybe we can
21:21I can talk to you after we run this one.
21:23It's a little in the weeds. Yeah, I
21:24mean,
21:25uh,
21:26if it's like a OIDC based connection,
21:28then yeah, the scopes that the client is
21:31requesting need to match what the server
21:34will allow. And if there's a mismatch
21:35there, there's kind of different ways
21:37you can handle it, but like you
21:39shouldn't grant obviously scopes that
21:40weren't, you know, allowed. Um, so that
21:43might be we can talk about it and can
21:45see uh, if that's the issue. Yeah, Entra
21:47doesn't
21:48support DCR.
21:50Mm, yeah. set up a proxy come back. Now
21:53needs to be aware of which client is
21:55coming in to
21:56uh,
21:57tweak a few headers before sending it
21:59across the network. I wonder if like
22:02Yeah, uh, the question was Entra doesn't
22:03support DCR, so that creates issues.
22:05Yeah, that's um,
22:07uh, kind of I think a general problem in
22:09the wild is, you know, which clients and
22:11which servers support all the, you know,
22:13as the MCP spec develops. Um, so I would
22:16say like most clients and servers
22:19support DCR at this point, but obviously
22:20not everyone does and there's
22:23not a lot you can really do if uh, you
22:25know, one doesn't support it. You have
22:26to like, you know, go register, you
22:27know, in the case if it's not DCR, you
22:28have to go pre-register that client. Um,
22:31you know, CIMD is like the new standard
22:33that's kind of supersedes uh, DCR. It's
22:36um,
22:37uh, command or
22:40I actually forgot what the CI stands
22:41for. It's metadata it's like a metadata
22:43document that defines clients up front,
22:44so you don't have to create the clients
22:45every time. Um, but that one has even
22:48less broad support in the ecosystem cuz
22:49it's, you know, it's like three months
22:51old. Um, but it is like a better
22:52experience. So, yeah, there's still a
22:54little bit of um,
22:55catch-up in the ecosystem to, you know,
22:58uh, supporting like the latest spec.
23:01I'll catch up. Cool, yeah.
23:05Great. Well, thanks everyone for your
23:06time. Have a great rest of the
23:07conference.