1
00:00:00,000 --> 00:00:02,260
Have you ever opened a config file and thought,

2
00:00:02,260 --> 00:00:04,460
"I really hope nobody finds this connection string"

3
00:00:04,460 --> 00:00:06,380
or maybe you've been the person who accidentally pushed

4
00:00:06,380 --> 00:00:08,900
a secret to GitHub and spent the next hour rotating keys

5
00:00:08,900 --> 00:00:10,340
before anyone noticed?

6
00:00:10,340 --> 00:00:12,380
If you've worked with Azure for any length of time,

7
00:00:12,380 --> 00:00:13,980
you've dealt with the credential problem.

8
00:00:13,980 --> 00:00:16,060
Service principles with client secrets,

9
00:00:16,060 --> 00:00:18,660
certificates that expire at the worst possible moment,

10
00:00:18,660 --> 00:00:21,500
connection strings spread across repos and deployment scripts.

11
00:00:21,500 --> 00:00:23,020
It's a mess.

12
00:00:23,020 --> 00:00:23,860
But here's the thing,

13
00:00:23,860 --> 00:00:25,820
what if your app didn't need secrets at all?

14
00:00:25,820 --> 00:00:27,660
What if you could give it its own identity

15
00:00:27,660 --> 00:00:29,140
just like you give a person one

16
00:00:29,140 --> 00:00:30,620
and let Azure handle the rest?

17
00:00:30,620 --> 00:00:32,820
Think of it like a digital ID card for your app

18
00:00:32,820 --> 00:00:35,380
that ID card shows Azure who the app is

19
00:00:35,380 --> 00:00:36,580
and what it's allowed to do.

20
00:00:36,580 --> 00:00:39,220
And that's exactly what managed identities are all about.

21
00:00:39,220 --> 00:00:41,620
In this episode, we're breaking down what they are,

22
00:00:41,620 --> 00:00:43,020
the two types you need to know

23
00:00:43,020 --> 00:00:45,260
and why Microsoft is betting on this approach

24
00:00:45,260 --> 00:00:46,620
for Azure security.

25
00:00:46,620 --> 00:00:48,940
By the end, you'll understand why managed identities

26
00:00:48,940 --> 00:00:52,100
are becoming the standard for any real Azure workload.

27
00:00:52,100 --> 00:00:54,420
The problem, secrets, secrets everywhere.

28
00:00:54,420 --> 00:00:56,460
Let's start with the old way of doing things.

29
00:00:56,460 --> 00:00:58,380
You build an app that needs to talk to Azure storage

30
00:00:58,380 --> 00:01:00,140
so you grab a connection string,

31
00:01:00,140 --> 00:01:01,700
then it needs to read from key vaults

32
00:01:01,700 --> 00:01:02,820
so you get another secret,

33
00:01:02,820 --> 00:01:04,140
then it has to write to a database

34
00:01:04,140 --> 00:01:05,540
which means another credential.

35
00:01:05,540 --> 00:01:06,540
Before you know it,

36
00:01:06,540 --> 00:01:07,860
you're managing a dozen different secrets,

37
00:01:07,860 --> 00:01:09,420
each one a ticking time bomb.

38
00:01:09,420 --> 00:01:11,660
Security people call this secrets brawl.

39
00:01:11,660 --> 00:01:13,580
Those credentials end up in app settings,

40
00:01:13,580 --> 00:01:15,620
environment variables, deployment scripts

41
00:01:15,620 --> 00:01:17,940
and sometimes hard coded and source code.

42
00:01:17,940 --> 00:01:20,820
A quick search on GitHub for accidentally committed secrets

43
00:01:20,820 --> 00:01:23,020
shows this isn't just a hypothetical problem.

44
00:01:23,020 --> 00:01:24,260
It happens every single day.

45
00:01:24,260 --> 00:01:25,620
Then there's the rotation problem.

46
00:01:25,620 --> 00:01:27,260
Rotating secrets every 90 days

47
00:01:27,260 --> 00:01:29,220
is what security best practices recommend.

48
00:01:29,220 --> 00:01:30,540
In theory, that sounds great,

49
00:01:30,540 --> 00:01:32,660
but in practice, nobody does it consistently.

50
00:01:32,660 --> 00:01:33,980
Teams forget, scripts break

51
00:01:33,980 --> 00:01:35,180
and then you have a certificate

52
00:01:35,180 --> 00:01:36,780
that expires at 3 a.m. on a Saturday

53
00:01:36,780 --> 00:01:39,060
taking your entire production environment down.

54
00:01:39,060 --> 00:01:40,620
The human factor makes it worse.

55
00:01:40,620 --> 00:01:42,340
Secrets get shared in emails,

56
00:01:42,340 --> 00:01:43,620
paste it into chat threads

57
00:01:43,620 --> 00:01:46,020
or written on sticky notes attached to monitors.

58
00:01:46,020 --> 00:01:47,180
When someone leaves the company,

59
00:01:47,180 --> 00:01:49,980
nobody remembers to rotate the credentials they had access to.

60
00:01:49,980 --> 00:01:52,580
Now scale that up to a microservices architecture

61
00:01:52,580 --> 00:01:54,700
where every component needs its own identity.

62
00:01:54,700 --> 00:01:56,340
Suddenly, you're not managing a dozen secrets,

63
00:01:56,340 --> 00:01:57,260
but 50.

64
00:01:57,260 --> 00:01:58,420
When something goes wrong,

65
00:01:58,420 --> 00:02:00,420
good luck figuring out which service did what,

66
00:02:00,420 --> 00:02:02,060
because audit logs become useless

67
00:02:02,060 --> 00:02:04,220
when multiple services share the same credential.

68
00:02:04,220 --> 00:02:05,500
You see an action happened,

69
00:02:05,500 --> 00:02:08,260
but you have no idea which service actually performed it.

70
00:02:08,260 --> 00:02:11,300
So Microsoft looked at this mess and asked a simple question,

71
00:02:11,300 --> 00:02:13,940
what if we just eliminated the secret entirely?

72
00:02:13,940 --> 00:02:15,900
The solution managed identity.

73
00:02:15,900 --> 00:02:17,100
So here's the idea.

74
00:02:17,100 --> 00:02:18,700
Instead of handing your app a secret,

75
00:02:18,700 --> 00:02:19,860
it has to keep safe.

76
00:02:19,860 --> 00:02:21,540
You give it an identity.

77
00:02:21,540 --> 00:02:23,500
A real identity inside Microsoft EntraID,

78
00:02:23,500 --> 00:02:24,740
just like a user account,

79
00:02:24,740 --> 00:02:27,220
but built for a workload as your creates it,

80
00:02:27,220 --> 00:02:28,300
ties it to your resource

81
00:02:28,300 --> 00:02:31,020
and handles all the credential management behind the scenes.

82
00:02:31,020 --> 00:02:32,460
You never see a password,

83
00:02:32,460 --> 00:02:33,620
you never generate a key,

84
00:02:33,620 --> 00:02:36,300
you never install a certificate, it just works.

85
00:02:36,300 --> 00:02:37,540
Now here's what's interesting.

86
00:02:37,540 --> 00:02:40,620
Under the hood, a managed identity is still a service principle.

87
00:02:40,620 --> 00:02:42,100
The same kind of object that exists

88
00:02:42,100 --> 00:02:44,660
when you register an app in EntraID.

89
00:02:44,660 --> 00:02:47,420
The difference is that you don't manage the credential.

90
00:02:47,420 --> 00:02:48,260
Azure does.

91
00:02:48,260 --> 00:02:49,420
It creates the identity,

92
00:02:49,420 --> 00:02:52,460
rotates the certificate automatically every 45 days or so,

93
00:02:52,460 --> 00:02:54,620
and if you're using a system assigned identity,

94
00:02:54,620 --> 00:02:57,140
it cleans everything up when the resource is deleted.

95
00:02:57,140 --> 00:02:58,580
No orphaned accounts,

96
00:02:58,580 --> 00:03:00,940
no expired secrets causing outages,

97
00:03:00,940 --> 00:03:03,580
no manual rotation scripts that nobody remembers to run.

98
00:03:03,580 --> 00:03:04,940
So how does it actually work?

99
00:03:04,940 --> 00:03:06,420
The magic happens through something called

100
00:03:06,420 --> 00:03:09,260
the Instance Metadata Service or IMDS.

101
00:03:09,260 --> 00:03:11,340
Every Azure resource has an internal endpoint

102
00:03:11,340 --> 00:03:12,820
at a specific IP address,

103
00:03:12,820 --> 00:03:16,580
169.254, 169.254.

104
00:03:16,580 --> 00:03:18,340
When your code needs to authenticate,

105
00:03:18,340 --> 00:03:20,580
it sends a request to this endpoint saying,

106
00:03:20,580 --> 00:03:23,020
I need a token for Azure storage.

107
00:03:23,020 --> 00:03:24,940
The Azure fabric checks that this resource

108
00:03:24,940 --> 00:03:27,140
actually has a managed identity enabled,

109
00:03:27,140 --> 00:03:29,860
and if it does, IMDS returns and access token,

110
00:03:29,860 --> 00:03:32,980
your code takes that token and uses it to call the service it needs.

111
00:03:32,980 --> 00:03:34,140
Think about what that means.

112
00:03:34,140 --> 00:03:35,500
Your code never sees a secret.

113
00:03:35,500 --> 00:03:36,460
It doesn't store one.

114
00:03:36,460 --> 00:03:38,260
It doesn't read one from a config file.

115
00:03:38,260 --> 00:03:40,060
It just asks for a token and gets one.

116
00:03:40,060 --> 00:03:42,180
The Azure platform itself acts as the proof

117
00:03:42,180 --> 00:03:44,140
that your app is who it says it is.

118
00:03:44,140 --> 00:03:47,060
This changes the entire mindset of building on Azure.

119
00:03:47,060 --> 00:03:48,060
The old way was,

120
00:03:48,060 --> 00:03:49,820
I need my app to talk to storage,

121
00:03:49,820 --> 00:03:51,340
so I need a connection string.

122
00:03:51,340 --> 00:03:52,340
The new way is,

123
00:03:52,340 --> 00:03:53,820
I need my app to talk to storage.

124
00:03:53,820 --> 00:03:55,980
Can I use a managed identity?

125
00:03:55,980 --> 00:03:58,100
And in almost every case, the answer is yes.

126
00:03:58,100 --> 00:03:59,260
Azure storage supports it,

127
00:03:59,260 --> 00:04:00,460
Key Vault supports it,

128
00:04:00,460 --> 00:04:02,260
SQL database, service bus,

129
00:04:02,260 --> 00:04:04,140
event hubs, Cosmos DB,

130
00:04:04,140 --> 00:04:05,380
the list keeps growing.

131
00:04:05,380 --> 00:04:07,340
When you're building a new Azure workload,

132
00:04:07,340 --> 00:04:09,300
managed identity should be your first thought,

133
00:04:09,300 --> 00:04:10,180
not an after thought.

134
00:04:10,180 --> 00:04:12,140
No more storing secrets in app settings,

135
00:04:12,140 --> 00:04:14,660
no more environment variables with connection strings,

136
00:04:14,660 --> 00:04:17,700
no more putting credentials in Key Vault just for authentication.

137
00:04:17,700 --> 00:04:20,460
You grant permissions directly to the identity using our back

138
00:04:20,460 --> 00:04:22,220
and the platform handles the rest.

139
00:04:22,220 --> 00:04:24,820
System assigned versus user assigned.

140
00:04:24,820 --> 00:04:27,220
Now let's talk about the two flavors of managed identities

141
00:04:27,220 --> 00:04:29,180
because this is where people get confused.

142
00:04:29,180 --> 00:04:30,220
They're not the same thing

143
00:04:30,220 --> 00:04:32,860
and picking the wrong one can cause headaches later.

144
00:04:32,860 --> 00:04:35,540
The core difference comes down to one word, life cycle.

145
00:04:35,540 --> 00:04:37,220
Who owns the identity's lifespan?

146
00:04:37,220 --> 00:04:39,780
Who decides when it's created and when it's destroyed?

147
00:04:39,780 --> 00:04:41,660
System assigned is the simpler of the two.

148
00:04:41,660 --> 00:04:43,140
You enable it on a resource,

149
00:04:43,140 --> 00:04:45,900
a virtual machine, an app service, a single function,

150
00:04:45,900 --> 00:04:47,460
and Azure creates an identity

151
00:04:47,460 --> 00:04:49,140
that is tied directly to that resource.

152
00:04:49,140 --> 00:04:51,340
They share a life when the resource is born,

153
00:04:51,340 --> 00:04:52,380
the identity is born.

154
00:04:52,380 --> 00:04:53,460
When you delete the resource,

155
00:04:53,460 --> 00:04:57,220
the identity is deleted too, one to one relationship.

156
00:04:57,220 --> 00:04:59,940
The beauty of System assigned is that there's almost no management

157
00:04:59,940 --> 00:05:00,700
overhead.

158
00:05:00,700 --> 00:05:01,940
You flip a switch in the portal

159
00:05:01,940 --> 00:05:04,060
or add a single line in your bicep template,

160
00:05:04,060 --> 00:05:04,900
and it's done.

161
00:05:04,900 --> 00:05:06,340
No separate resource to create,

162
00:05:06,340 --> 00:05:07,620
no cleanup to worry about.

163
00:05:07,620 --> 00:05:09,460
If you have a single web app that needs to read

164
00:05:09,460 --> 00:05:11,940
from its own storage account, this is your answer.

165
00:05:11,940 --> 00:05:13,820
Enable it, grant the role, move on,

166
00:05:13,820 --> 00:05:16,100
but there's a catch because the identity is tied

167
00:05:16,100 --> 00:05:17,260
to that specific resource.

168
00:05:17,260 --> 00:05:19,980
If you delete the resource, the identity disappears.

169
00:05:19,980 --> 00:05:21,260
That's fine if you're done with it.

170
00:05:21,260 --> 00:05:22,980
But what if you're migrating workloads?

171
00:05:22,980 --> 00:05:24,460
What if you need to rebuild a VM

172
00:05:24,460 --> 00:05:26,180
and want to keep the same identity?

173
00:05:26,180 --> 00:05:28,100
With System assigned, you'd have to re-enable it

174
00:05:28,100 --> 00:05:29,340
and re-ground permissions.

175
00:05:29,340 --> 00:05:31,180
Not a disaster, but an extra step.

176
00:05:31,180 --> 00:05:33,140
User assigned solves that problem.

177
00:05:33,140 --> 00:05:35,100
Here you create the identity as a standalone

178
00:05:35,100 --> 00:05:36,300
Azure resource first.

179
00:05:36,300 --> 00:05:39,340
It exists independently with its own life cycle.

180
00:05:39,340 --> 00:05:41,500
Then you attach it to one or more resources,

181
00:05:41,500 --> 00:05:44,180
virtual machines, app services, whatever you need,

182
00:05:44,180 --> 00:05:45,820
one identity, many resources.

183
00:05:45,820 --> 00:05:47,420
This is a many to one relationship.

184
00:05:47,420 --> 00:05:49,020
The identity lives on its own.

185
00:05:49,020 --> 00:05:51,060
You can delete all the resources that use it

186
00:05:51,060 --> 00:05:52,420
and the identity stays.

187
00:05:52,420 --> 00:05:55,260
You can attach the same identity to five different services

188
00:05:55,260 --> 00:05:57,060
and they all share the same permissions.

189
00:05:57,060 --> 00:06:00,300
That's incredibly useful when you have a shared development cluster

190
00:06:00,300 --> 00:06:03,740
where multiple services all need access to the same key vault.

191
00:06:03,740 --> 00:06:05,620
Instead of granting permissions five times

192
00:06:05,620 --> 00:06:07,180
to five different identities,

193
00:06:07,180 --> 00:06:09,780
you grant it once to a user assigned identity

194
00:06:09,780 --> 00:06:10,860
and attach it everywhere.

195
00:06:10,860 --> 00:06:11,940
So when do you pick which?

196
00:06:11,940 --> 00:06:13,380
Here's a simple framework.

197
00:06:13,380 --> 00:06:15,980
Use System assigned when you have a single resource

198
00:06:15,980 --> 00:06:17,540
that needs its own identity

199
00:06:17,540 --> 00:06:19,780
and you want zero management overhead.

200
00:06:19,780 --> 00:06:22,140
A web app that talks to its own database.

201
00:06:22,140 --> 00:06:24,620
A function that writes to its own storage account.

202
00:06:24,620 --> 00:06:26,700
A VM that needs to pull secrets from key vault,

203
00:06:26,700 --> 00:06:28,340
enable it, grant access done.

204
00:06:28,340 --> 00:06:30,540
Use user assigned when you need the same identity

205
00:06:30,540 --> 00:06:32,020
across multiple resources.

206
00:06:32,020 --> 00:06:34,300
When you want the identity to outlive the resources

207
00:06:34,300 --> 00:06:36,460
it's attached to, when you need to control

208
00:06:36,460 --> 00:06:37,980
the life cycle separately,

209
00:06:37,980 --> 00:06:39,700
maybe you want to pre-create identities

210
00:06:39,700 --> 00:06:41,420
in a central management subscription

211
00:06:41,420 --> 00:06:43,340
and let application teams attach them.

212
00:06:43,340 --> 00:06:45,340
User assigned gives you that flexibility.

213
00:06:45,340 --> 00:06:47,380
One more thing, user assigned identities

214
00:06:47,380 --> 00:06:48,780
are regional resources.

215
00:06:48,780 --> 00:06:50,740
You create them in a specific region

216
00:06:50,740 --> 00:06:52,500
but the service principle behind them

217
00:06:52,500 --> 00:06:54,260
lives in enter ID globally.

218
00:06:54,260 --> 00:06:56,620
So you can attach a user assigned identity created

219
00:06:56,620 --> 00:06:58,740
in East, US to a resource in West Europe.

220
00:06:58,740 --> 00:07:01,620
The identity works anywhere as you are runs.

221
00:07:01,620 --> 00:07:03,500
How they actually work under the hood.

222
00:07:03,500 --> 00:07:05,060
So what actually happens when your code

223
00:07:05,060 --> 00:07:06,660
uses a managed identity?

224
00:07:06,660 --> 00:07:07,860
Let's walk through the flow.

225
00:07:07,860 --> 00:07:10,100
Your code needs to talk to Azure storage.

226
00:07:10,100 --> 00:07:11,540
Instead of reading a connection string

227
00:07:11,540 --> 00:07:14,220
from a config file, it calls the identity endpoint.

228
00:07:14,220 --> 00:07:16,060
If you're using the Azure SDKs,

229
00:07:16,060 --> 00:07:18,820
this happens automatically through default Azure credential.

230
00:07:18,820 --> 00:07:20,340
You don't write any special code.

231
00:07:20,340 --> 00:07:21,940
You just create a blob service client

232
00:07:21,940 --> 00:07:23,380
without passing credentials

233
00:07:23,380 --> 00:07:25,900
and the SDK handles the rest.

234
00:07:25,900 --> 00:07:28,140
That request hits the instance metadata service

235
00:07:28,140 --> 00:07:31,540
at 169.254, 169.254.

236
00:07:31,540 --> 00:07:32,940
Think of it like an internal phone number

237
00:07:32,940 --> 00:07:34,380
that every Azure resource has.

238
00:07:34,380 --> 00:07:35,940
You can't reach it from your laptop

239
00:07:35,940 --> 00:07:37,820
that only exists inside the Azure fabric.

240
00:07:37,820 --> 00:07:40,380
IMDS then checks with the Azure control plane.

241
00:07:40,380 --> 00:07:42,500
Does this resource have a managed identity enabled?

242
00:07:42,500 --> 00:07:43,820
If not, you get an error.

243
00:07:43,820 --> 00:07:46,260
If it does, the platform confirms the identity.

244
00:07:46,260 --> 00:07:47,980
Next, IMDS returns an access token.

245
00:07:47,980 --> 00:07:50,140
It's a standard OAuth 2.0 token

246
00:07:50,140 --> 00:07:52,020
like any other token from EntraID.

247
00:07:52,020 --> 00:07:53,900
It includes the identity's client ID,

248
00:07:53,900 --> 00:07:55,940
the target resource and a timestamp.

249
00:07:55,940 --> 00:07:58,900
The token is short-lived, typically 60 to 90 minutes.

250
00:07:58,900 --> 00:08:01,860
Your code takes that token and calls Azure storage.

251
00:08:01,860 --> 00:08:04,780
The storage service validates the token against EntraID

252
00:08:04,780 --> 00:08:05,940
and checks the ABIAC permissions

253
00:08:05,940 --> 00:08:07,780
you assigned to the managed identity.

254
00:08:07,780 --> 00:08:09,780
If the identity has storage blob data reader

255
00:08:09,780 --> 00:08:12,140
on that storage account, the request goes through.

256
00:08:12,140 --> 00:08:13,420
If not, you get a 403.

257
00:08:13,420 --> 00:08:16,540
Here's the thing, at no point did your code handle the secret.

258
00:08:16,540 --> 00:08:19,660
The platform itself proved the resources identity.

259
00:08:19,660 --> 00:08:21,740
The Azure fabric knows what resources running,

260
00:08:21,740 --> 00:08:24,660
where it's running and that it has a managed identity.

261
00:08:24,660 --> 00:08:25,940
It's not checking a password.

262
00:08:25,940 --> 00:08:27,580
It's checking the resources, existence,

263
00:08:27,580 --> 00:08:29,180
and configuration inside Azure

264
00:08:29,180 --> 00:08:31,620
compared that to the old service principle approach.

265
00:08:31,620 --> 00:08:33,380
You needed three things, the tenant ID,

266
00:08:33,380 --> 00:08:36,260
the client ID, and a client's secret or certificate.

267
00:08:36,260 --> 00:08:38,300
Your code has to read those values from somewhere.

268
00:08:38,300 --> 00:08:40,460
Environment variables, key vault, a config file,

269
00:08:40,460 --> 00:08:42,580
every one of those is a potential leak point.

270
00:08:42,580 --> 00:08:44,300
Everyone requires manual rotation.

271
00:08:44,300 --> 00:08:46,340
Everyone is something an attacker could steal.

272
00:08:46,340 --> 00:08:49,420
With managed identities, your code doesn't specify any of that.

273
00:08:49,420 --> 00:08:51,940
Default as your credential automatically detects.

274
00:08:51,940 --> 00:08:53,740
It's running inside an Azure resource

275
00:08:53,740 --> 00:08:55,340
with a managed identity and uses it.

276
00:08:55,340 --> 00:08:57,420
If you run the same code locally on your laptop,

277
00:08:57,420 --> 00:08:59,100
default as your credential falls back

278
00:08:59,100 --> 00:09:00,660
to your personal developer credentials.

279
00:09:00,660 --> 00:09:03,300
You don't change the code, you don't change the configuration.

280
00:09:03,300 --> 00:09:05,700
The SDK handles the environment detection for you.

281
00:09:05,700 --> 00:09:07,660
The tokens refresh automatically.

282
00:09:07,660 --> 00:09:09,300
Your code doesn't worry about expiration.

283
00:09:09,300 --> 00:09:12,060
The SDK caches the token and requests a new one

284
00:09:12,060 --> 00:09:13,500
before the old one expires.

285
00:09:13,500 --> 00:09:14,700
This all happens in the background.

286
00:09:14,700 --> 00:09:16,900
You just call the service and it works.

287
00:09:16,900 --> 00:09:18,020
One thing to be aware of,

288
00:09:18,020 --> 00:09:20,380
permission changes don't take effect instantly.

289
00:09:20,380 --> 00:09:23,060
Because tokens are cached for up to 24 hours on the back end,

290
00:09:23,060 --> 00:09:25,820
if you grant a new R-back role to a managed identity,

291
00:09:25,820 --> 00:09:28,380
it might take a while before the identity can use it.

292
00:09:28,380 --> 00:09:29,540
This is by design.

293
00:09:29,540 --> 00:09:32,300
It reduces load on the authentication infrastructure,

294
00:09:32,300 --> 00:09:34,620
but it means you can't expect instant propagation.

295
00:09:34,620 --> 00:09:35,900
If you need immediate access,

296
00:09:35,900 --> 00:09:37,380
you might need to restart the service

297
00:09:37,380 --> 00:09:39,580
or wait for the cache to clear.

298
00:09:39,580 --> 00:09:42,020
Real-world scenario from dev to production.

299
00:09:42,020 --> 00:09:43,260
Let's make this concrete.

300
00:09:43,260 --> 00:09:45,860
Imagine a simple web API that writes to Azure storage

301
00:09:45,860 --> 00:09:47,660
and reads secrets from Key Vault.

302
00:09:47,660 --> 00:09:49,700
We'll follow it from your laptop to production

303
00:09:49,700 --> 00:09:51,220
in development you're running locally.

304
00:09:51,220 --> 00:09:54,180
Visual Studio, VS Code, whatever tool you use.

305
00:09:54,180 --> 00:09:55,620
Default as your credential kicks in

306
00:09:55,620 --> 00:09:57,700
and picks up your personal developer credentials.

307
00:09:57,700 --> 00:10:00,020
The same ones you use to sign into the Azure portal.

308
00:10:00,020 --> 00:10:01,740
You don't need a managed identity here.

309
00:10:01,740 --> 00:10:03,380
You don't need a service principle.

310
00:10:03,380 --> 00:10:05,580
Your own user account handles authentication

311
00:10:05,580 --> 00:10:07,140
while you're building and testing.

312
00:10:07,140 --> 00:10:08,220
Now it's time to deploy.

313
00:10:08,220 --> 00:10:10,380
You push your code to Azure app service.

314
00:10:10,380 --> 00:10:12,340
First thing you do is enable system assigned

315
00:10:12,340 --> 00:10:14,180
managed identity on that app service.

316
00:10:14,180 --> 00:10:17,220
One toggle in the portal or one line in your bicep template.

317
00:10:17,220 --> 00:10:18,460
That's it.

318
00:10:18,460 --> 00:10:20,260
Next, you grant permissions.

319
00:10:20,260 --> 00:10:22,540
Your API needs to write blobs to a storage account

320
00:10:22,540 --> 00:10:24,100
and read secrets from Key Vault.

321
00:10:24,100 --> 00:10:25,540
You assign two R-back roles.

322
00:10:25,540 --> 00:10:28,060
Storage Blob Data contributor on the storage account

323
00:10:28,060 --> 00:10:30,500
and Key Vault secrets user on the Key Vault.

324
00:10:30,500 --> 00:10:32,980
Both assigned to the managed identities principle ID.

325
00:10:32,980 --> 00:10:34,260
Notice what you didn't do.

326
00:10:34,260 --> 00:10:35,980
You didn't generate a connection string.

327
00:10:35,980 --> 00:10:37,340
You didn't create a client secret.

328
00:10:37,340 --> 00:10:38,980
You didn't store anything in app settings.

329
00:10:38,980 --> 00:10:40,460
You didn't put credentials in Key Vault

330
00:10:40,460 --> 00:10:41,780
just to retrieve them later.

331
00:10:41,780 --> 00:10:43,940
You granted permissions directly to the identity

332
00:10:43,940 --> 00:10:45,660
and the platform handles the rest.

333
00:10:45,660 --> 00:10:47,180
The app starts working immediately.

334
00:10:47,180 --> 00:10:48,500
No secret rotation scripts.

335
00:10:48,500 --> 00:10:49,780
No expiry dates to track.

336
00:10:49,780 --> 00:10:51,260
No works on my machine problems

337
00:10:51,260 --> 00:10:52,980
because the authentication method changes

338
00:10:52,980 --> 00:10:54,220
between environments.

339
00:10:54,220 --> 00:10:56,740
Default as your credential handles that transparently.

340
00:10:56,740 --> 00:10:57,980
Now you scale out.

341
00:10:57,980 --> 00:11:00,340
You add more instances to your app service plan.

342
00:11:00,340 --> 00:11:02,340
Every new instance automatically shares

343
00:11:02,340 --> 00:11:04,500
the same system assigned identity.

344
00:11:04,500 --> 00:11:06,420
You don't need to configure anything.

345
00:11:06,420 --> 00:11:08,300
The new instances start serving requests

346
00:11:08,300 --> 00:11:10,220
and authenticating with the same identity

347
00:11:10,220 --> 00:11:11,380
using the same permissions.

348
00:11:11,380 --> 00:11:12,260
It just works.

349
00:11:12,260 --> 00:11:14,540
But then you add a second service, a background processor

350
00:11:14,540 --> 00:11:16,060
that reads from the same storage account

351
00:11:16,060 --> 00:11:17,300
and processes files.

352
00:11:17,300 --> 00:11:20,180
This is where user assigned identities shine.

353
00:11:20,180 --> 00:11:21,660
Instead of enabling system assigned

354
00:11:21,660 --> 00:11:24,100
on the processor and granting the same permissions again,

355
00:11:24,100 --> 00:11:26,100
you create a user assigned identity.

356
00:11:26,100 --> 00:11:29,380
You granted storage Blob Data Reader on the storage account.

357
00:11:29,380 --> 00:11:30,940
Then you attach that same identity

358
00:11:30,940 --> 00:11:33,460
to both the web API and the background processor.

359
00:11:33,460 --> 00:11:35,380
One permission granted to services covered.

360
00:11:35,380 --> 00:11:37,180
Now consider environment isolation.

361
00:11:37,180 --> 00:11:39,780
You want separate identities for dev, test, and prod.

362
00:11:39,780 --> 00:11:42,180
With user assigned identities, you create three,

363
00:11:42,180 --> 00:11:43,380
one per environment.

364
00:11:43,380 --> 00:11:46,300
Each one gets permissions scoped to its own resources.

365
00:11:46,300 --> 00:11:49,180
A token obtained in dev cannot reach production.

366
00:11:49,180 --> 00:11:50,940
Even if someone somehow extracts a token

367
00:11:50,940 --> 00:11:53,140
from your dev environment, it's worthless against

368
00:11:53,140 --> 00:11:53,980
prod resources.

369
00:11:53,980 --> 00:11:56,260
The audience and the permissions simply don't match.

370
00:11:56,260 --> 00:11:57,540
Your deployment pipeline itself

371
00:11:57,540 --> 00:11:59,380
doesn't need to handle secrets either.

372
00:11:59,380 --> 00:12:02,020
The CI/CD runner, whether it's Azure DevOps, GitHub

373
00:12:02,020 --> 00:12:04,340
actions, or something else, can use a managed identity

374
00:12:04,340 --> 00:12:06,300
to deploy resources and assigned permissions.

375
00:12:06,300 --> 00:12:09,380
No service principle secrets stored in pipeline variables.

376
00:12:09,380 --> 00:12:11,580
No certificate files uploaded to the build agent.

377
00:12:11,580 --> 00:12:14,180
The pipeline authenticates using its own identity,

378
00:12:14,180 --> 00:12:15,660
granted through R-Back.

379
00:12:15,660 --> 00:12:17,460
The old world versus the new world.

380
00:12:17,460 --> 00:12:20,020
Let's put this side by side so you can really see the difference.

381
00:12:20,020 --> 00:12:22,260
In the old world, you'd create a service principle,

382
00:12:22,260 --> 00:12:25,500
generate a client secret, and store that secret in Key Vault.

383
00:12:25,500 --> 00:12:27,780
Then you'd write code to retrieve it at runtime.

384
00:12:27,780 --> 00:12:29,140
You'd set up a rotation schedule.

385
00:12:29,140 --> 00:12:32,540
Every 90 days, generate a new secret, update Key Vault,

386
00:12:32,540 --> 00:12:35,300
test that nothing broke, and hope you didn't miss any of the places

387
00:12:35,300 --> 00:12:36,420
that secret was used.

388
00:12:36,420 --> 00:12:38,180
That's a lot of moving parts, and one mistake

389
00:12:38,180 --> 00:12:39,620
could bring everything down.

390
00:12:39,620 --> 00:12:41,580
In the new world, you enable managed identity,

391
00:12:41,580 --> 00:12:43,700
assign an R-Back role, and you're done.

392
00:12:43,700 --> 00:12:44,980
No secret to rotate.

393
00:12:44,980 --> 00:12:46,740
No Key Vault call just for authentication.

394
00:12:46,740 --> 00:12:49,260
It's like having a smart badge that works everywhere automatically.

395
00:12:49,260 --> 00:12:50,180
That's the magic of it.

396
00:12:50,180 --> 00:12:52,060
The old world had a specific failure mode

397
00:12:52,060 --> 00:12:53,940
that kept security teams up at night.

398
00:12:53,940 --> 00:12:55,620
A developer checks in a secret by accident,

399
00:12:55,620 --> 00:12:57,420
and suddenly you have a security incident.

400
00:12:57,420 --> 00:12:59,860
You're rotating the secret, notifying the team, auditing

401
00:12:59,860 --> 00:13:01,340
who might have accessed it.

402
00:13:01,340 --> 00:13:02,420
All hands on deck.

403
00:13:02,420 --> 00:13:05,060
In the new world, there are no secrets to check in.

404
00:13:05,060 --> 00:13:07,420
The credential doesn't exist in your code base or your config

405
00:13:07,420 --> 00:13:08,140
files.

406
00:13:08,140 --> 00:13:10,660
It exists only inside the Azure fabric, managed,

407
00:13:10,660 --> 00:13:12,940
and rotated automatically by the platform.

408
00:13:12,940 --> 00:13:15,700
The old world also had what I call the 3am problem.

409
00:13:15,700 --> 00:13:17,700
A certificate expires on a Saturday night.

410
00:13:17,700 --> 00:13:19,060
Your production environment goes down.

411
00:13:19,060 --> 00:13:22,020
You get paged, you scramble to generate a new certificate,

412
00:13:22,020 --> 00:13:24,740
update the service principle, restart the service.

413
00:13:24,740 --> 00:13:27,020
Meanwhile, your users stare at error pages.

414
00:13:27,020 --> 00:13:29,740
In the new world, Azure rotates the credential for you.

415
00:13:29,740 --> 00:13:31,660
Every 45 days or so, the certificate

416
00:13:31,660 --> 00:13:34,140
behind your managed identity is replaced automatically.

417
00:13:34,140 --> 00:13:35,540
You never even know what happened.

418
00:13:35,540 --> 00:13:37,380
No outage, no 3am phone call.

419
00:13:37,380 --> 00:13:39,060
The security implications go deeper.

420
00:13:39,060 --> 00:13:41,860
Managed identity tokens are tied to the Azure control plane.

421
00:13:41,860 --> 00:13:44,820
They're fishing resistant because there's no user involved.

422
00:13:44,820 --> 00:13:46,980
The token is obtained by the resource itself

423
00:13:46,980 --> 00:13:49,700
through a channel that only exists inside Azure.

424
00:13:49,700 --> 00:13:52,220
If an attacker breaches your app, they can access what

425
00:13:52,220 --> 00:13:54,140
the identity has permission to access,

426
00:13:54,140 --> 00:13:56,780
but they can't steal the credential because there's nothing

427
00:13:56,780 --> 00:13:57,580
to steal.

428
00:13:57,580 --> 00:13:59,060
And governance gets simpler, too.

429
00:13:59,060 --> 00:14:01,780
When you delete a resource with a system assigned identity,

430
00:14:01,780 --> 00:14:03,500
the identity is automatically cleaned up.

431
00:14:03,500 --> 00:14:06,140
No often service principles lingering in enter ID

432
00:14:06,140 --> 00:14:07,780
with permissions you forgot about.

433
00:14:07,780 --> 00:14:09,620
No audit findings asking why an identity

434
00:14:09,620 --> 00:14:11,380
from a decommissioned project still has

435
00:14:11,380 --> 00:14:13,540
contributed access to a production subscription.

436
00:14:13,540 --> 00:14:15,060
The platform handles the cleanup.

437
00:14:15,060 --> 00:14:16,420
That's the kind of simplification

438
00:14:16,420 --> 00:14:19,060
that makes Azure security easier to manage.

439
00:14:19,060 --> 00:14:21,140
When not to use managed identities.

440
00:14:21,140 --> 00:14:22,820
So if managed identities are so much better,

441
00:14:22,820 --> 00:14:24,620
why doesn't everyone use them for everything?

442
00:14:24,620 --> 00:14:26,660
The hard limitation is that managed identities

443
00:14:26,660 --> 00:14:29,580
only work inside Azure that on-premises backup server

444
00:14:29,580 --> 00:14:30,500
in your data center.

445
00:14:30,500 --> 00:14:33,460
It can't use a managed identity because it's not running

446
00:14:33,460 --> 00:14:33,980
on Azure.

447
00:14:33,980 --> 00:14:36,580
There's no IMDS endpoint for it to talk to.

448
00:14:36,580 --> 00:14:38,860
Same for your self-hosted GitHub actions runner.

449
00:14:38,860 --> 00:14:40,420
If it's not an Azure resource, you

450
00:14:40,420 --> 00:14:42,340
need a traditional service principle

451
00:14:42,340 --> 00:14:44,300
with a client secret or certificate.

452
00:14:44,300 --> 00:14:46,060
Multi-cloud setups run into the same wall.

453
00:14:46,060 --> 00:14:48,220
If you have workloads on AWS or GCP that

454
00:14:48,220 --> 00:14:51,060
need to authenticate to Azure, managed identities won't help.

455
00:14:51,060 --> 00:14:52,940
Those services aren't inside Azure's fabric,

456
00:14:52,940 --> 00:14:54,700
so they need service principles.

457
00:14:54,700 --> 00:14:56,900
Third party SaaS tools that need to authenticate

458
00:14:56,900 --> 00:14:59,140
to your Azure resources, same problem.

459
00:14:59,140 --> 00:15:00,780
They're not running on your Azure subscription.

460
00:15:00,780 --> 00:15:02,380
They can't use your managed identities,

461
00:15:02,380 --> 00:15:04,060
but Microsoft is making progress here.

462
00:15:04,060 --> 00:15:06,620
Workload identity federation lets external services

463
00:15:06,620 --> 00:15:08,820
exchange their own identity tokens

464
00:15:08,820 --> 00:15:11,460
from GitHub, Kubernetes, or other identity providers

465
00:15:11,460 --> 00:15:13,300
for intra-ID tokens.

466
00:15:13,300 --> 00:15:15,300
It's not as seamless as a managed identity,

467
00:15:15,300 --> 00:15:17,500
but it's a step toward reducing secrets everywhere,

468
00:15:17,500 --> 00:15:18,740
not just inside Azure.

469
00:15:18,740 --> 00:15:19,740
Here's the rule of thumb.

470
00:15:19,740 --> 00:15:22,940
If your workload runs on Azure, use managed identities.

471
00:15:22,940 --> 00:15:24,700
If it doesn't, use service principles

472
00:15:24,700 --> 00:15:26,660
with key vault and automated rotation.

473
00:15:26,660 --> 00:15:28,940
And keep an eye on workload identity federation.

474
00:15:28,940 --> 00:15:31,980
It's closing the gap for workloads outside Azure.

475
00:15:31,980 --> 00:15:33,220
Actionable takeaways.

476
00:15:33,220 --> 00:15:34,940
So what can you actually do starting today?

477
00:15:34,940 --> 00:15:37,620
Here are a few simple steps that will make a big difference.

478
00:15:37,620 --> 00:15:41,220
First, go through your existing Azure resources, app services,

479
00:15:41,220 --> 00:15:44,980
functions, VMs, anything that supports managed identities.

480
00:15:44,980 --> 00:15:48,460
If you find one without managed identity enabled, turn it on.

481
00:15:48,460 --> 00:15:50,180
It takes seconds and it costs you nothing.

482
00:15:50,180 --> 00:15:51,260
No reason not to do it.

483
00:15:51,260 --> 00:15:53,820
Next, pick one specific service to convert.

484
00:15:53,820 --> 00:15:55,900
Storage or key vault are perfect candidates.

485
00:15:55,900 --> 00:15:57,220
Replace that old connection string

486
00:15:57,220 --> 00:15:59,620
sitting in your app settings with a managed identity

487
00:15:59,620 --> 00:16:01,140
and an R-Backroll assignment.

488
00:16:01,140 --> 00:16:01,900
Run a quick test.

489
00:16:01,900 --> 00:16:04,260
You'll see how much cleaner your configuration looks

490
00:16:04,260 --> 00:16:06,460
when there are no secrets hiding in plain sight.

491
00:16:06,460 --> 00:16:08,460
Finally, for any shared infrastructure

492
00:16:08,460 --> 00:16:10,580
like a development cluster or a set of microservices

493
00:16:10,580 --> 00:16:12,380
that all need the same permissions,

494
00:16:12,380 --> 00:16:14,340
use a user assigned managed identity

495
00:16:14,340 --> 00:16:15,660
instead of duplicating permissions

496
00:16:15,660 --> 00:16:18,100
across multiple system assigned identities.

497
00:16:18,100 --> 00:16:20,060
One identity, one set of R-Backrolls,

498
00:16:20,060 --> 00:16:21,740
and you can attach it everywhere it's needed.

499
00:16:21,740 --> 00:16:22,580
It's that simple.

500
00:16:22,580 --> 00:16:24,020
This isn't just a nice to have anymore.

501
00:16:24,020 --> 00:16:26,100
Microsoft is making mandatory MFA mandatory

502
00:16:26,100 --> 00:16:27,140
for service principles,

503
00:16:27,140 --> 00:16:29,780
but managed identities bypass that requirement completely

504
00:16:29,780 --> 00:16:32,180
because there are no user credentials to protect.

505
00:16:32,180 --> 00:16:33,940
Your future self will thank you when you avoid

506
00:16:33,940 --> 00:16:36,980
that 3am on call alert about an expired certificate.

507
00:16:36,980 --> 00:16:39,460
Managed identities let you give your apps their own identity

508
00:16:39,460 --> 00:16:41,180
without ever touching a secret.

509
00:16:41,180 --> 00:16:43,180
That's the real shift from managing credentials

510
00:16:43,180 --> 00:16:44,580
to managing permissions.

511
00:16:44,580 --> 00:16:46,700
Subscribe for more simply explained breakdowns

512
00:16:46,700 --> 00:16:48,100
and drop a comment letting me know

513
00:16:48,100 --> 00:16:50,220
which as your service you want covered next,

514
00:16:50,220 --> 00:16:52,540
making Microsoft make sense one nugget at a time.

