-Hey, this is Michael Dyrynda. -And this is Jake Bennett.
And welcome to Episode 179 of the North Meet South Web Podcast.
I thought it was 180. 179, huh?
Yeah.
-179, okay. Well, hey- -Next- next- next week, we'll get to 180.
179 it is, folks. Um,
it is post July 4th, and I'm still sort of hanging on to the mustache thing here-
-It's fine -... a little bit.
I can- I can... Look, the goatie, th-
-the dirty goatie I can live with. -It- it's okay.
The mustache...
-I'm gonna shave it all off for- for- -Maybe, maybe
... Laracon again. And now you're just gonna have to live with, uh, Jake with the
mustache.
Um, no, I'm not actually not gonna do that. I'm gonna- I'm gonna- I'm gonna just
put it all back to how it- how it should normally be. Um, but in other news-
-I was just- -We- we are actually staying at the same
hotel.
-I'm pretty stoked. -Yes, finally.
-Finally, yes. -That- that worked out well in the end.
-It did end up working out well. -Worked out well in the end because
I said back in February, like, "I've bo- bought my ticket, I've booked my
-accommodation-" -Yep, yep.
"... this is the closest hotel." And it ended up- ended up- ended up being one of
-the- -Yeah, the conference, yeah
... the official, I guess, conference hotels.
And so by the time you booked, three weeks before the event-
Yeah.
-You're like, "There's no rooms anywhere." -Yeah, you were like, oh-
-I wonder why, you know? -Right, yeah. And so they ended up opening
-up, and, uh, yep. -1,200 people-
-So- -1,200 people coming in. Yeah, so that
-worked out. -It's gonna be awesome. I'm so excited. We
can do, like, pillow fights middle of the night, just like-
-Pillow fights. -Yep.
-Yeah, yep. -Just gonna find out whose room is it. We
gotta have- have so many people there. Knock on the doors and just hit people
-with pillows. It's gonna be good times. -It's gonna be a bit like that. It's, um...
Yeah, I looked, 'cause I, um, I messaged Matt, Matt Stouffer, and I said, "What are
we doing for coffee?" Because I know it's only three days, but I can't drink
-Starbucks for three days. -Yep.
-Like, that's not an option. -Yep, yep.
I need good coffee. It turns out... Now, whether or not it is good is to be seen,
but it turns out that in that hotel, in the Vib by Best Western, for those of you
who are staying there, there is a coffee, there's, like, a cafe-
-Nice. Okay, okay -... downstairs in the hotel.
So it- it has, like, a four-and-a-half star rating, so I'm hoping-
-Sweet -... that that's good enough.
-That'll be good. -There is also, for those of you staying
there, a taqueria downstairs. So tacos and coffee, we should be sorted.
Sounds amazing. Yeah, I'm- I'm really excited. It looks like a really nice hotel
-as well. Um, like you said- -Mm-hmm
... it's like, I think the closest hotel to the venue of the ones that there are
-on- -Yeah
-... that are on there. So, um- -Mm-hmm
... yeah, it's- it's gonna be amazing. I'm so excited. I cannot wait. I'm flying in
Monday, leaving Thursday evening. So if any of you have no plans for Thursday,
meaning you've stayed Wednesday, you did the afterparty on Wednesday, you slept in
on Thursday, and now it's Thursday afternoon and you're looking for something
to do, hit me up on Telegram. I'd love to hang out because Michael will probably be
gone by then. Michael, will you be out by then?
-Yeah. -Yeah, so I'll be leaving at 5:30-
-Yeah, we- we get in at, like, 3:00 -... which means I'll have a bit of time
-for lunch. -Yeah.
I'll be able to... I'll be free for lunch if anybody wants to hang out.
-Yeah, we get in at 3:00-ish on- -Monday, yep
... Monday, Aaron and I. And then, we were supposed to leave at 6:00 or something
-like that, 6:00 PM on Thursday. -Yeah.
But our flight got pulled back to 11:00 AM.
-Ah. -So we're probably gonna be at the airport
at, like, I don't know, 8:00, just to be safe.
-Yeah. -Just who knows?
Yeah, we can catch coffee. You and I can catch coffee.
Although I saw recently... Yeah, yeah, we'll be all right. We'll- the- we'll have
plenty of opportunities to- to see each other over the- the three days-
-For sure -... that- that we're there, but
yeah, I am... I saw- I saw on the news or something, there was an article the other
day that, like, tourism is way down for Australians into
-the US at the moment, like 12 or 15%- -Wow, that's crazy
-... on what they were expecting normally. -Yeah.
So I'm- I'm hoping that we have, like, a lo- although these- these flights that we
bought were on sale, so they're sale dates, so I suspect that maybe they will
be booked-booked. But it'd be nice to see if there's a bit of, uh,
-bit of space on the plane actually. -Some extra legroom. Yeah, for sure.
-Yeah. -I actually-
-We'll see what happens -... there was a lady sitting in my seat on
the last flight I was on.
And I didn't bother her 'cause, like, it doesn't matter, there's extra seats. And
so I told the attendant, I was like, "Do you mind if I sit in another seat?" And
she's like, "Yeah, that's fine." I said, "Why- why don't I just go sit in first
class, it's like it's enough, should I sit up there?" She was like, "It's fine with
me." She's like, "But let me check." And so she checked and the lady up front was
like, "No". I was like, "Come on", so I just took an exit seat. It was fine.
-Ah, you tried. -I did try. She was almost, I mean, almost
-had her. -You tried.
-Yep. I was almost there. -Almost. Almost there. Almost got it. Yeah,
we- we definitely for the long haul flights, the, uh, Sydney to Dallas and
then the LA to Melbourne on the way back, we-
-we went for exit seats. -Nice, there you go.
-Aaron and I just- -Yeah, some extra room.
Um, and hopefully these are good exit seats because the last time I was coming
back from the US, I went
thinking that it'd be good to sit in the, like, the- the bulkhead row-
-Yeah -... behind the- the bathrooms.
-Yeah. -Terrible idea. Don't ever do that. Because
-number one, the armrests- -Oh, no.
Like, the armrests are fixed, so you can't move them. So I had, like... I was
uncomfortable the whole time. And you think because you're at the bulkhead,
there's a bit more room, and there is physically a bit more room to stretch your
legs out. But the problem is people walk past there to go-
-Oh, God. -... to the bathroom from the bathroom. So
yeah, no good. So we are on the... We're by the galley,
um, on the exit- exit row this time, and to, like, the- the- the left of the plane.
So hopefully that'll be a better seat. But I didn't... I looked at even premium
c- premium economy was like $6,000 return or something like that.
-My gosh. -I said, "Nah. Not."
-Hey, okay, I've got one- -No thank you, not for me
... one quick tip for you here
-for sleeping on planes. -Mm-hmm.
Okay?
There is this amazing product called the Sleeper Hold.
-Sleeper Hold. Is- -Right.
-No, seriously. It was invented by an- -Nonsense
-... an MMA guy, a UFC fighter- -Mm-hmm
... who had to go on flights and trips and stuff like that all the time. And he was,
like, sick of, like, not being able to sleep well on these- on these trips.
-Mm-hmm. -So he invented this thing called the
Sleeper Hold. Now, I got one at a conference. I was like, "What is this
nonsense?"Oh, my gosh. I will never travel without it again. It is amazing, and you
can actually sleep well on flights or on buses or on-
-Right -... on anything like that- ... that has,
like a rest... Like, a seat behind you.
It is incredible. So if you... I mean, because you're gonna be on these insane
flights, you know, you're gonna be hitting 14 and a half hour time difference jet
lag thing,
I would suggest snapping one of these up. Now, they're not inexpensive, but they are
amazing, amazing. And so, um, check it out. Sleeper-
Oh, the travel pillow. Right, right, right, right.
Sleeper Hold. Yeah, yeah. It's a s- it's a no-
-When you say sleeper hold- -And I know, and I know, it's- it's not,
-you know, it's not just a travel pillow. -Yeah.
-It's- it's- it's a little bit different. -Yeah, yeah, yeah.
They've got some really good marketing as well, but I've actually used it and the
marketing holds up. The hype holds up. It's really good. So for any of you
listening who are gonna be going to Laracon, grab a Sleeper Hold. Tell them
Jake sent you, there's no referral code or anything. Sorry, otherwise I would give
it to you. But, uh, they're pretty sweet. Pretty sweet. So...
Right. So this thing, you strap to the... You strap to the seat, and it kind of
holds your head so your face doesn't flop forward.
That's right. Yeah, so you have a little neck thing that-
-Yeah, cool -... goes behind, just behind the- the,
like, the little dip in your neck, in the back of your neck. You just put the pillow
-there- -Mm-hmm
... and then there is a strap that goes around the back of the seat. And then
there's like a eye mask that kind of goes over the front of your eyes and holds your
head in place up against the back of the seat. And you don't, you know-
-Yeah, right -... those neck cushions, they don't
actually hold your head up, so you- you kind of, you have to try-
-Yeah, yeah, yeah -... lean your head back. It doesn't work
very well. This works amazingly, and I have slept like a baby on flights with
-this thing. So, highly suggest it. -I'm, uh... I have sent this to my wife.
-Mm-hmm. -I am very fortunate in that I, generally
speaking, on a flight, will close my eyes and wake up eight or nine hours later.
-That's amazing. -Especially on the way back. Especially on
the way back, because it'll be, you know, three days of go, go, go. We've got the-
the mostly technical party on Monday night.
-Yep, Monday night. -We've got after dark on- on Tuesday night,
then there's like... I assume we'll do something on-
-Wednesday night, yeah. Did you- -... on Wednesday night as well, and then
-we're gonna be up- -There's a link, I'll send it to you.
-There's a Luma something. -Yeah, yeah, yeah. I-
-You get that one? -Yes, that was for Tuesday night, I think,
-that one. Yeah, I got that one s- -I think that was-
-So, did that, um... -I thought that- I thought that was for
Wednesday.
Let me look.
-Luma after party. -Can you double check?
Yep, I'm looking right now. Tuesday. You're right, it is Tuesday. Yep.
-Mm-hmm. -My bad.
Yeah.
Yeah, so, um, that, and then Wednesday night, I assume we'll do something. Go
-grab dinner or something- -Yeah, yeah
... with the- with the guys. Anyone who's- who's keen for that.
-For sure. -Um, and then Wednesday we'll be up early,
and then we're just gonna have to try and power through LA. Um, Aaron and I are
gonna go and do the unthinkable. And I don't know if we're actually gonna do
this, but I- I joked to Aaron, I said, "So, outside of LAX, there's a Five Guys,
-an In-N-Out, and a Chick-fil-A." -Gotta do it.
And I'm like, "We'll just eat all of them. We'll just do all three."
You gotta do it.
And then, uh, yeah. So
by the time I get on that plane, and- and this has happened every time I've left the
US for- for any trip that I've been over there, I'm asleep before wheels up. Like,
before we leave the ground- ... my eyes are shut. I'm out.
Yeah.
-Oh, my gosh. -And they come- they come at like an hour
or- or- or two later, and they're like, "Do you want dinner?" I'm like, "It's
midnight. I don't- I don't want dinner. Go away."
-That's funny. -"Why did you wake me up for this?" So...
-That's hilarious. -This light- this light keeps on flicking
off and on for some reason, I don't know why. So every now and then I get shrouded
in darkness.
-Well- -So yeah, Laracon, uh, this-
Anyway, long story short. Yeah, absolutely
... this will be our last- last North Meet South before Laracon. Uh, we've got...
We'll do an episode of Laravel News next week. Mm-hmm.
And then we'll be on location.
Is it that quick? No. Oh, no. We will have one more North Meet South before Laracon.
Okay. Okay.
And then we'll be on location. Yep, yep, yep, yep, yep.
So yeah. A- and then for Laravel News, you and I will be,
uh, running around. You did a day one recap last year with-
-Yes -... David Hemphill.
-Yes. -Which made- made me feel very slighted,
-uh, that you would- -I'm so sorry.
... you would do something like- like that .
I think I mentioned you. I thought I mentioned you.
-You did- you did mention me. -Okay.
But, uh, you know, I will- I will- I'll be there this time, so you watch yourself.
And so it will definitely be you and me. Yeah, Hemphill. Watch it, you're gonna
-get- you're gonna get a- -So yeah, we'll do-
-... shiv. -We'll do a recap day one and we'll do day
two, 'cause there was no day two last year.
-Right. -Um, and I think we're gonna go around and
-do some like vox pops- -Absolutely
... and speak to people and- and talk to them as well for Laravel News, so that'll
be a bit of fun. Something- something to do.
-Should be a good time. -So if- if you are interested
in doing that, keep an eye out for us. We'll- we'd love to talk to you about what
you think. I saw Taylor's got like a two-hour
-keynote at the end of day one. -Wow.
So that'll be- that'll be a bit of fun. And looks like there's a lot of variety in
the talks as well. If you've- if you've seen the schedule, there's some- there's
some, um, you know, 30-minute talks, 20-minute talks. They're all over the
place this year, which- which is good. I think- I think mixing things up like that
is- is good for the audience as well. Um, getting a- a mix of lengths and types and-
and all sorts. So
-very excited to get back over there- -Yeah
... after, what, six years or whatever it's been.
Yep. It's gonna be incredible to have you, dude. It's been too long. Too long since
we've been able to hang out in- in, uh, the real, right? In 3D.
-Mm-hmm. -So it'll be fun. It'll be lots of fun. Hey
folks, we have a couple different topics that I would like to talk about today. The
first one is this. Should you have
a middleware call inside the constructor of a controller? Okay, so
set it up for you.
This is something that used to be supported and I do not think it's
supported anymore in Laravel 12, which is this. Inside of a controller you can, in
the constructor, say, "This middleware," and then specify a middleware. And what
this will do is this will apply that middleware to anything that you're going
to be accessing that controller
through, right? Any route that references anything that points to that controller,
you can have a middleware in the constructor of that controller. Okay. Are
you ready?
Think about it for a second. Make up your mind. Do you think you should put it there
or not?
And
go. All right, what do you think, Michael?
No. And you, you, you posted this the other day-
-I did -... in Telegram, and I-
I'm gonna grab a water while you formulate your response and, and tell me why I
shouldn't do it, so then I can actually come back and tell you why I think you
should. But go ahead.
Yeah.
I mean, Laravel 12, you said you can't do it, so that's, that's as good a reason as
any to not do it. Um, I know
there used to be some explicit reason to do it. Like, you... There was some part of
the request lifecycle that wasn't available inside of
your route definitions, which is why you, you maybe wouldn't have done it
previously. Like, you wanted to dynamically apply a middleware or
something like that inside of the controller constructor.
The, the reason I don't
like the idea of putting the middleware in the controller
is kind of similar to why I don't like using, um,
events too much. I don't particularly like using observers and, and global scopes,
although those things are a little bit more
-opaque now- -Yeah, for sure they are
... because we've got the attributes to say, like, observed by, scoped by, and all
of that kind of stuff. But I feel like
the routes file is the first place that I'm going to look in a new application to
see everything that's happening across the application. Like, I know what
functionality is available, I know where to reach it. It's a very quick and easy
way. W- this is the same reason I don't like route definitions inside of
controllers using attributes, which is a thing that has-
-Fair enough -... like, come and gone in the past.
Because if you want to s- I mean, you can always do a route list and see the route
list that way, but I think opening up the routes file and just scrolling through it
and seeing everything that's there is my preferred method for, for dealing with
that kind of stuff.
When you start putting things in- inside a constructor, it's, it becomes
less visible.
Um, it... Like, does it still appear in the route list if you d- define a
-middleware there? -That's a good question. I honestly don't
-know. -'Cause that would be my hesitation.
-I'm not sure. -Yeah. 'Cause that would be, that would be
-another hesitation of mine- -I kinda feel like it wouldn't
-... is that you don't know. -I kinda feel like it would not. Yeah.
Yeah.
Um, so yeah, my, eh, I never, I never do. Um,
all of my middlewares are defined inside of
-the routes file. Yeah. -Fair enough. Now that being said, uh, I
mean there are multiple other places where there are middlewares being placed onto
things without your knowledge or just explicitly by the framework. So,
you know, one of those places is in the
bootstrap, uh, app.php file, where you're-
-Mm-hmm -... setting up all your routes and all
those things. And if you use a then, uh, portion of the section there when you're
defining those different routes, then you can apply middlewares there and things
like that. You know, you can set up a new stack essentially. You have web, you have
API, you have console, which are all getting set up. You have up, which is also
another one that ships by default with Laravel 11.
But if you have a then, you know, you might do something like development
routes. Like, if you're in development, you will, then you'd bind these
development routes, and you could put, uh, prefixes or middlewares on it in there.
Uh, there was previously in, you know, previous versions where you had a, a route
service provider or something like that, or the HTTP kernel, you could do things in
-there as well when you'd register those- -Mm-hmm
... or when you'd bind those sorts of things. And so, it's not like it's only
ever been that the routes file is the only place where middlewares are applied. I
-mean, there's a web- -Right.
There's a web stack that's applied by default.
-Yeah, yeah. -So
I get the argument that, like, if you can just go see the web.php, you can see
everything on there, but it's not actually true. Like, there's... That's all the
-things- -Mm-hmm
... that you would put on there, but it's definitely not all-
-Yeah -... the things that are on there.
-Yeah. -So, um, I would say that, like, as far as
the user definitions are defined, I agree that the web.php is where you would go see
all the user-defined things most of the time. Um, you do have to be a little bit
careful if you're migrating from legacy applications, and that's the situation
here. That's why we ran into this, is we've... You know, we've been on this
since Laravel 4, and so this very particular application has been upgraded
to 4, 5, 6, 7, 8, 9, 10, 11, 12. And so, 12-
-Yeah -... is when it sort of-
-Yeah -... dropped support for it and caused some
issues for us. The one thing I will say that is helpful, and maybe the reason why,
um, what you were talking about, is like if you wanted to resolve something out of
the constructor in order to be able to apply that to a middleware or s- pass that
in as something to the middleware, it's possible that at one point that was not
available. But obviously now you can make your own middleware classes and things
like that, so it's not a problem. Um,
but
if there is a middleware that you want to apply to every single method inside of
that controller,
it is possible for someone to miss that when they're defining a new route for that
controller, right? Maybe they don't look and see the other places. Maybe that
control... Maybe the, the locations where, uh, those are defined are not co-located.
Maybe they're just adding a new one to the bottom of the list and they don't go
find it. That controller middleware, uh, is not gonna be applied now. And so,
that could be problematic. Now, that's... Maybe there's ways around that. Maybe you
can put an architecture test in place. But that was the particular argument that I
had, which was like, it's not necessarily all bad to be able to define it in the
controller. I can see the arguments for why you maybe wouldn't,
-but I don't think it's- -Mm-hmm
... I don't think it's that bad. I don't know. I don't know.
Yeah.
I'm just trying to look back on when, when it was actually... 'Cause there's nothing
in the Laravel 12 upgrade guide that I can see
that's obvious that says this has been
removed. So...
-All I know is it was throwing an error. -Controller middleware.
-Yeah. -Oh no, it's still here.
-It was throwing an error. -Controller middleware.
-Go ahead. Yeah, maybe just- -Ouch
-... maybe the way that we defined it. -Oh, you put it... Yeah. So used to be in
a, um,
cons- in the construct method, and now you can define it as a stat- a public static
method that returns an array inside the controller.
I got it.
-So it's still able to be used- -And you, and you implement the has
-middleware -... just not in the same way. Oh, I see. I
-see. -Mm-hmm.
Yep. Just not in the same way. Okay. Fair enough.
Fair enough. Middleware may be assigned to the controller's routes in your routes
file. You may find it convenient to specify middleware within your controller
class. To do so, your controller should implement the HasMiddleware interface,
which dictates that the controller should have a static middleware method. From this
method, you may return an array of middleware that should be applied to the
controller's actions, and you may also define ControllerMiddleware as closures-
-Hmm, interesting -... which provides a convenient way to
define an inline middleware without writing an entire middleware class. But it
doesn't,
doesn't really say why or when you would do this-
-Sharp knives -... which I guess is... You know, sharp
knives, right? Laravel
provides many ways to do the same thing. I would, I would posit that doing it inside
of the controller is potentially a less,
um,
what's the word?
Like, a less conventional way of doing it.
-I agree. I do agree with that. -But, you know, it's documented. Um,
yeah. I don- I mean,
yeah, i- for... I wouldn't do it in the controller for the same reason that I
wouldn't,
that I don't subscribe to, to doing route definitions inside of the controller.
-And that's fair. -Um...
I, I do get that. Yeah, and, and so it sounds like it's not necessarily... Th-
the method by which we were using it is deprecated, but the, the idea itself-
-Mm-hmm -... is still very much documented and
relevant inside of Laravel. So, fair enough. I, I think that's, uh... You know,
it's again, sharp knives, use them if you want to, uh, if you don't... If you cut
-yourself- -Yeah
... don't complain, right? Just deal with it. So...
Yeah.
It's certainly like a top level documentation item.
-Yeah. -Right? It's
in, on this page, introduction, writing controllers, controller middleware. So
it's not hidden. It's not one of those things that, like, gets pushed
down the documentation until one day it disappears and then you know that it's...
It,
it likely won't ever be removed.
Eh, in, you know, the way that Laravel typically handles deprecations, is just
that at some point
it's determined to be not the best practice or, you know, there's another way
of doing it that's, that's more appropriate or more, uh, efficient or
whatever else. And so the documented approach becomes the way to do things, and
stuff that drops out
might get deprecated eventually, you know, in two or three major releases time. But,
um, it typically survives even though it's not documented. So it's still, still
there as a top level thing. But
yeah, I don't, I don't see where this... I, I'd have to dig to find out, you know,
why you would do it in a constructor. Like, what, what was the documented reason
-for doing it- -Yeah
-... essentially? -Yeah. I, I don't even know if I could tell
you in this case. I, I think it... This one is honestly just... It was like a
authorization check to see if somebody had a particular role or something like that,
-that's all it was. -Mm-hmm. Mm-hmm.
Like, "Can they do this particular thing?" If they can't do this particular thing,
then there's no reason for them to see the view, the update, the create, the delete.
Th- they shouldn't be able to do any of that stuff, like, don't bother even-
-Right -... doing a policy on it. There was...
This was before policies were a thing. You just said, "At the controller level,
don't bother, just abort. Before they ever do anything with it, just abort."
Which brings me to my next question.
Um, unless you have anything else you wanna talk about, which I... So, I've got
-one more thing and that's- -No, no, go for it.
-Okay. Okay. -Are you... You meant, you, you, you
floated this, like you got in early with this one, so you've... It's obviously on
-your mind- -It is
-... so let's talk about- -Yes. Okay. So we talked about this with
the other devs on the team earlier today. Okay. So
I'm gonna try and set up the world for you a little bit and then we can chat. And I
think you can help me point out maybe some p- some potential flaws,
or maybe not flaws but pitfalls that I might be looking into or that I might need
to investigate and/or better ways to structure this. Okay, so here it is.
-Mm-hmm. -Let's say I have 20 apps, which I do, and
let's say that each of those applications has, currently has their own roles.
And the way that we're checking permissions or abilities inside of any of
these locations and inside of any of these applications is only through checking of
if a user has a role. Okay? So that is, that is the way that we've done it. Now,
the problem with that
is that the onl- if you only define roles, the only way to give somebody permission
to do something is to assign them a role.
Does this make sense?
-So- -Mm-hmm. Yep
... if you have a person, let's say that there's a manager who's stepping out for a
week and they have a person on their team who's like their number two, right,
assistant to the regional manager if you will. And they need this , they need this
user to sort of take their place, interim, uh, manager, uh, for a week. The only
way, i- but they really only need them to do one part of their job, which is that
they need to run this report every day and send it to the CEO. Let's say that's the
-deal. -Yeah.
Right? That's it. That's all they need to do.
But because the only way to give them that permission is to assign them that role,
in addition to getting the ability to run the report, they also get the ability to
put in coaching entries or reprimand other peop- or s- read entries for other
teams', um, employees or team members that are on that team, right? Not what you're
-asking for, not what you're looking for. -No.
Certainly, like, not a least privileged situation. And so what we're running into
is that we have people who have permissions that they should never have
just because they were given them temporarily and then they were never
removed. Right? So the only way that we can catch this is if we do these audits,
which we end up doing, but it's a big pain in the neck. And there are ways, there
are better ways to do this. So,
I'm gonna ex- I'll explain to you sort of our proposition and then I'll continue to
kinda go through how we wanna manage it. The proposition is in any place where we
have a HasRoleCheck, we're gonna remove that HasRoleCheck and we're going to name
the thing that they're trying to do at that check. So, instead of
HasRole, we're going to s- HasRoleManager, we're gonna say CanRunReports. In that
spot, that one spot where they check to see if they ha- if they're a manager.
Instead we're going to say name that thing that they're trying to do, they're trying
to run a report, and then we're going to ask the question User CanRunReports.
Right? Okay. So we're going to change it from a role to a permission or ability.
Permission and ability are the same word, essentially. Which do you prefer?
Mm-hmm. I I think the, the general advice, like the 90%, 95% use case, is to assign
-roles and check permissions. -Okay. Permissions.
It's certainly the way that, that we operate, is that we will always check that
-the user can do something. -Yeah. Okay.
We would never... Well,
I say never. In our modern stuff , in our new stuff, it's always a permission check.
Okay.
Uh, or a policy check or whatever else. Previously, in our old code, it w- it was
-base... Like, we would assign roles. -Yeah. Yeah.
We had a permissions table, but p- but permissions were never implemented, so it
was always like, "Is... Does this user have a role?"
-Yeah. -We would always check are they an admin,
-are they a manager. -Yep.
Are they a group manager. We had, um... And, and like you say, that then means
that that person has access to everything
that that role enables them,
um, whereas you want, typically, I think, your permissions to be as granular as
possible.
Yes. The... Yes, correct. I agree with all of that. Um, my question specifically is,
when we're talking about that, you're using the word permissions to talk about a
granular level thing that they can do. Another word that I've heard used for that
-is ability. So, my question is- -Mm-hmm
... for the remainder of our discussion, would you prefer me call them permissions
or abilities?
It depends on what you... If you're just using Lyro stuff, I'd call them
-permissions. -Okay. So, yeah, permissions. And that's
-what my guys sort of said too. They said- -And you-
... "Oh, we like to call them permissions instead of abilities." 'Cause I've called
-them abilities- -Yeah
... in the past, and I th- we can call them-
-Yeah -... permissions. That's fine.
-It's a bit... Like, I think bouncer? -Yes.
'Cause I know you've used bouncer in the past.
Well that, well that's because of abilities.
Bouncer refers to the roles and abilities.
-Yeah. Yeah. -Yeah, right. Um, I think... How would you
-think about this? -And then there are no permissions, we're
first giving out permissions.
Yeah.
Like, you have permission to do something, but you have the ability
to
-enact that, that something, right? -Yeah. Yeah.
So, I think it depends on which way you're looking at... You know, is the user
the one that... You know, does the user have the ability to do this thing?
-It- -I know. They're, they're synonymous.
-The user has the ability- -They're synonymous. Yeah.
Or does the user have the permission? Yeah.
Yeah. And so, I'm just trying to establish, like, uh, the domain language
for our team, like, whether we're gonna be using the word ability, permission. I've
-used the word ability- -Yeah
... but I think we're switching over to using the word permission.
Sounds like if the rest of your... Yeah, I was gonna say, it sounds like if the rest
-of your team- -Yeah
-... is using permission- -Yeah, that's the word that they would like
-to use -... then, then you're using permission.
-Agreed. -Um, and like I said, I, I think the, the
fact that
ability is in your head is probably owing to the fact that you used-
-100% -... that you've used bouncer in the past
-as well. -Yes, it is.
But, like, the Sparcy, Sparcy has a permissions package.
-Yeah. -I think generally when people speak about
-it, it's permission rather than... Yeah. -Yeah. Okay. So,
we've got permissions, right? In every spot where we're doing the HasRole, we're
going to check, uh... Instead of HasRole, we're gonna say HasPermission essentially.
Think about it that way, right? So, we're gonna make everything very granular, and
so our application will check for permissions. Now,
the second part of this is imagine that across those 20 apps, you know, every app
has its own set of permissions that, that are a part of that, right?
-Now- -Mm-hmm
... who manages those permissions is the question. Who gets to manage those? Well,
I will tell you, my preference is that I never ever manage those. I want my team to
write the code that enables people who have that permission to do that thing.
-That's what I want my team to do. -Mm-hmm.
But I do not want my team to manage permissions. I want the IT staff to do
that.
-Um- -Right
... and
for them,
even only in a limited capacity. So, um,
what I would like to have happen then is if you can think of a
different application... So you have these 20 applications that live on the bottom
level there, and all those le- all those are doing is they're checking for
abilities. So, there is essentially no,
no concept of roles anymore in those. We're gonna rip those out of that
application. No roles anymore. It's just permission checks. We're gonna go up a
layer, and now you're gonna have an application, uh, one layer above that
knows about all the different applications
and then knows about all the different roles in those applications, and then
groups together different permissions for those particular roles.
-Mm-hmm. -Does that make sense? Now, that
application that sits above that is active directory, essentially, is the idea,
-right? -It's exactly what that is. Yeah.
I mean, that's what it is. And so, and so what we're thinking is, like, why reinvent
the wheel on that? E- essentially what we do is we have a user,
and that user will have a job function, which is essentially their job title,
right? So if I have a banking manager,
um, that banking manager is going to have specific permissions inside of each of
those 20 different applications, right? Inside of some of those applications, they
may have a role of manager. So, like in the case of, like, coaching, right?
-Mm-hmm. -Because they're a manager, they're going
to have likely a coaching manager role inside that application, but the
application doesn't know anything about that. All it knows about at the end of the
day is which permissions that user was granted when they come in.
The way that this will be structured then in Active Directory is you will have a
coaching_,
so it's actually namespaced in Active Directory. App_coaching, which is the name
of the app, _role or ability. So,
app_coaching_manager. That's the role, right?
-Mm-hmm. Mm-hmm. -And then nested underneath that
would be additional security groups that would apply to that particular role,
right? So app_coaching can add new coaching log.
App_coaching-
-Yep -... can run coaching reports.
And those abilities may only live under app coaching manager, but they also may
run under... May live under app coaching admin.Right? So those abilities have
basically a one-to-many relationship between-
-Mm-hmm -... those, uh, those different security
groups. Okay? And then each user would get assigned to one of those security roles.
Okay. The reason why that's all important is because
when a user is created in the system, they will get a single
set of
roles. That's it, that's what they get. They get the ones that belong to their
particular job function and nothing else.
-So if- -Mm-hmm
... that user that was previously mentioned needs to take over for their
manager for a week to run that report,
instead of giving them
app_coaching_runreport, or sorry, a- app_coaching_manager, they would get the
ability of app_coaching_cannrunreport. They would get that single ability rather
than the manager role. Now here's the really interesting thing.
We are going to say that anybody who needs an additional permission outside of the
ones that apply to their specific role, they only get a lease on that permission.
-Yeah. -Does that make sense? So it's-
-Yep -... expiring, meaning that they can ask
for it for a period of time, and then after that, it goes away. It gets removed-
Yeah
-... from their user- -Yeah
... so that we don't end up with this mess of what we're talking about, where a user
gets a permission and it just is signed forever. So you have somebody who started
in one team and they've moved three times, and now they have inherited permissions
for every single team they've ever been on.
-Yeah. Mm-hmm. -Which is a freaking disaster mess.
-Um- -Yeah
... and it's really unclear what they actually still need and what they don't
-because they were never removed. -Mm-hmm.
-Yeah. -And so
that's the big picture of what we're trying to-
-So- -... accomplish. Yeah.
Mm-hmm. So are these, the expiring permissions, are they being managed inside
of Active Directory, or are you doing that, like some scheduled task that goes
through and, and cleans up these permissions where expiry date is in the
-past? -Yeah, you got it. And so it's actually a
little bit silly. We're using AD LDAP, so Active Directory-
-Mm-hmm -... L- LDAP. What is, uh, listing
directory? I don't know. It's, like, that protocol basically that lets you-
-Yeah, yeah, yeah -... talk to those things.
-Yeah. -And what we do is when somebody wants an
additional permission, we can say, "Okay, they want..." You know, select the
application you're trying to get permissions for. Coaching. "All right,
here are all the ab- roles and the abilities that are available for you to
lease." "Okay, I want to be able to run the report." "Okay. When does it, when
does it expire?" "It expires in, in a week." And then they say, "Okay, request."
Their manager has to look at it, approve it, and once their manager approves it, it
will then
send that off to our auth application, and then that thing actually adds that, uh,
group...
-Uh, sorry, adds that user- -Mm-hmm
-... sorry, to that group. -Yeah.
And then
it will, you know, check the end date every day at 7:00 AM, and when the end day
hits, it will remove that user from that group. And then when they log in the next
time, it will look at the AD groups that they are a part of and it will remove the
ability that they previously had, uh, when they logged in-
-Right -... last time.
-Mm-hmm. -So that's the idea. Now the, the big
challenges that I'm running into here is that this top level app,
uh, that's going to help manage all these things has to be aware of all the
different mappings that I have for these abilities inside of all these different
-applications, which is- -Yeah
... that is the pain, but I don't really know of a better way to do it if I don't
-want- -Yeah
... my team to manage it.
Yeah. And it also means that anytime you add a permission
somewhere, you've gotta do it in two places.
-Yes, correct. -You've gotta do it in the app, and you've
-gotta do it in the- -Active Directory
-... the overseer- -Yeah
-... as well. -Yeah.
Yeah.
But yeah, I mean, and, and expiring permission is a good way to, to deal with
it, I think, especially from a compliance perspective.
-Yeah, exactly. -You know, no one should have access to
things that they shouldn't have access to, so having that-
-And we can see when they requested it -... That's amazing. And it's like...
Yeah. Yeah, if you're keeping audit trail of it, that's, that's gonna be helpful for
that kind of stuff as well, 'cause you know that no one's got access to anything
that they shouldn't. And if they do, you know, they shouldn't typically have access
to it. You know when they requested it, when it was approved, by who, and when it
was removed. And, um,
yeah, I mean, it's no different to how when you create GitHub tokens and things
like that, you can request for it to be, you know, seven days or 30 days or 90 days
or, or, or unlimited. And as much as it annoys me every 30 days to have to, to
-roll a token- -I know, right
... I think probably having a, a 30 day token is, is still the, the correct answer
for most things.
-Yeah, there's, um, the- -Spreaker. Spreaker on the pitch.
Yeah. Oh, he's
...
He-
he's got his, uh, he's got his pajamas on. Harrison, you wanna say hi
real quick? Come here. Come here. Yeah, that's fine.
-The baby of the bunch. -Har- come say hi here. Hold on. Hold on.
Let me put your head phone.
-Look at him. -Say, say hey, Michael.
Hi, Michael. So big.
Hey, man. How you doing?
He's s-
-He's doing good. -I remember the, the last time I saw him
was teeny tiny in a pram
in New York.
-That's how long ago that was. -Oh, that's right. Dude, that was Laracon.
-No, look at him. -Harrison, you were in Laracon.
-Yeah. -You were at Laracon with us at eight weeks
old, remember?
You don't remember.
-I don't remember. -No, he don't remember. All right, say,
say, "Hello world."
Say it l- nice and loud to everybody.
Hello world.
-There he is. -I love the eye roll. Sorry.
Sorry. Bye, Harry.
Um,
so, uh, yeah, what was the last thing I was gonna s- oh, here's the other piece of
this which is really interesting, I think.
Um, if, so
when a permission is about to expire, we can send an email out and say, "Hey, you
have this permission which is about to expire. If you need to extend your lease
-on it- -Mm-hmm
... you can request, uh, an extension here." And they could click it. It could
-fire- -Yeah
... off that extension request, and then their manager could approve it again, and
then it could happen. Right. So I think it re- and so what that allows essentially,
is that allows me to not only actually remove the burden from my software
development team, it actually also removes the ability of my IT guys to get
involved. They'll have to add new permissions-
-Mm-hmm -... but they should never really have to
get involved in the modifying of permissions outside of-
-Yeah -... if we need to add a default permission
to a particular job function or job role. Right? Um...So it'll be a little bit of
like a hand in glove situation where we do need to work closely with them on some of
those things. But as it is right now, it's sort of a pain the neck because
they'll have to message one of the software devs and be like, "Hey, somebody
said they need to run that report. What role do they need?" That's, that's...
'Cause there's, it's not transparent to them at all-
-Yeah -... what, what roles are needed for what
particular abilities. And so
it's just we're trading problems, and I think it's a better solution.
Yeah.
-So. -So two, two things that I just thought of.
Number one, um, how easy are you making it? So if I have to go and request
permission to do some report, is it fairly obvious that I'm like, "This is the
permission that I want"?
-Right. Like- -Are you naming them in such a way? 'Cause-
Yeah
... most, most permission stuff would be transparent to... I mean, maybe managers
know what the permissions are. You know, there would be some level of knowledge
there depending on their technical skill. But for most, most workers, I would
imagine that they don't know what they're asking for.
That's agreed. That- that's true. And I think right now, it's completely obli- n-
-nobody knows. There's no good catalog- -Yeah
... of abilities, right? And so what we would have to do as part of this is we'd
have to... You know, we'd give it a good name, and we've got a convention that
we're using to convert the abilities, um,
to good named AD security objects. And then we need to give good definitions to
them as well. A- and so that'll be part of-
-Yeah -... the process of converting these over,
is just making sure that we give good descriptions of what they are. And then
we'll probably have to do something like a package, honestly, something that's going
to help to coordinate the different abilities between the different
applications. Or we'll have to create an endpoint that lives on these applications
where they can be hit and queried, and then they can return back those, those
pieces of data. 'Cause I really don't wanna have to
update...
I- I don't wanna have to update a package every time I wanna add a new ability. I
-don't wanna have to do that. And so- -Right
... I think if we just created an endpoint that was like, "Hey, give me all the
different ability. Give me, give me your permissions catalog," and it could, it
could say what those are, then we can just essentially advertise that and, you know,
use an API token, go grab the abilities, uh, the abilities catalog, and then, um,
push those into a config item or something like that. You know what I mean? I'm not
-using the- -Yeah
-... right wording here, but that- -Yeah
... that would be the idea. So yeah, that, I think-
-Yeah -... that would be how you'd do it. You
would try and make it as obvious as we could. So that was, that was number one.
Yeah.
-And you had number two. -Um, I think the, the other thing, the
other thing was, you know, if, if you needed to request an extension... I mean,
you, you said at the top that
people would be asking for permission to do something because their manager is
-going to be away. So if they need- -Ah
... to extend that, who's, who's approving that?
-Yeah, no. -Because the manager's obviously, you know,
-away for a bit longer, so there's- -That's a good-
-... that's something to consider as well. -That's a good question. Um-
Like, someone would have to approve it,
-um- -Yeah
... and they would probably... Like, I would, I would say that that is more the
exception than the norm, where maybe, you know, your team or IT would have to step
-in and go- -Yes
... "Well, they had it."
Yeah, typically, that, that has happened before.
-But then you'd have- -Yeah, where, where we would have somebody
-who's away- -And I think you would probably have some
-rules around that as well. -Yeah.
Like, you can only request one extension, or the extension can only be for two days
-or something like that. -Yeah.
And we did a, we did a similar kind of thing with,
um, like invoices. When you've got an overdue invoice, you can request an
extension. And so the, the frontline staff would have permission to request an
extension, and there'd be, there was a series of rules. Like, you could, you
could ask for s- uh, 14 days or seven days, but you could only ask for each
once. So initially, you'd get like a 14-day buffer. And then if you had already
asked for 14 days, you could only ask for a seven-day extension from there.
And then there was like... that was it. And that was, like, enforcing business
rules ar- around those kinds of things. Because there's also this expectation of,
um... This was in telecommunications, so there's, there's a whole code of practice
around, um, not
l- allowing customers to get, you know, dig themselves into debt-
-Yeah, yeah -... over these kinds of things that, you
know, you would have to, you'd have to cut them off. You wouldn't be able to keep
extending them so that you didn't keep charging them for a service that they
-clearly can't pay for or- -Yeah
... or had no interest in paying for. So,
um, yeah, maybe something like that where, you know, you get one,
one, um, bump. You know, it gives you an extra three days or something.
And then beyond that, you have to ask for a whole new thing.
-Yeah. -Um,
that, you know... Yeah, w- what that looks like for, for your organization and, and
how you implement that or what the, what the business rules around that is,
you know, up to, up to you guys. But it might be one approach that, that could be
-suitable. -It's a good idea to have a maximum number
of, um, extensions that you could do though. I think that's a great idea. It's
-not something- -Right
... I'd thought of before. 'Cause yeah, otherwise you could just have somebody
continue to request extensions and just kind of go that way. And-
-Mm-hmm -... that does defeat the purpose a little
bit, especially if we have, like, long-term leases.
You could ask for a new... Yeah, but you could, you could ask for a new-
-Correct -... extension.
-Yes. Absolutely. Yeah, you- -But it would, like, you couldn't just, you
couldn't have like a seven-day extension for the time that manager's away, and then
you would just ask for like... I would just top that up for another three days,
-another three days- -Yeah
... another three days. Like, you would wanna set a cap on that.
-Yeah. -But if they, there was genuinely a need
for it, you know, if the manager had delegated the responsibility of running
that report to someone else, then, you know, that would just have to request that
-permission, you know- -Absolutely
-... and say, "Okay, yes-" -And we have, I think the solution-
"... let's do it again. Here's another seven days or here's 30 days now."
Yeah, the solution in that instance would be like these long-term leases that we
-would have, that would be like- -Mm-hmm
... you could request up to like a six-month lease or something like that. If
-you're- -Yeah
... if, you know, in some instances, maybe it'd go through an additional approval
process or something where it's like, "Why are you asking for a six-month approval?"
Mm-hmm.
Uh, you have to have the approval of two... Or sorry, a six-month lease, you
have to have the approval of two people in order to get that or something. Um, and
if it was gonna be made a more permanent part of a role or delegated to somebody
else, then we might need to make an additional layer, an initial role, like a
training, uh, assistant. You know what I mean? Something like that role. And then
they just get that ability as well. Um, but again, the nice thing about this is
that if we needed to make that role, we would not have to be involved with that at
all. That decision can be made higher up the chain-
-Mm-hmm -... and we just check for the ability.
-Yeah. -So it's really nice.
-Yeah. -It allows the IT teams-
-Yeah. The roles can be created whenever. -You got it.
Yeah, roles can be created whenever, as long as they're composed of existing
-permissions. -You got it exactly right. And so I think
that really frees them up to do a lot of work. Now-... um, the, the trick is naming
the abilities well, and then the second trick is making sure that they kinda stay
in sync across this, uh, orchestrating, uh, entity that, th- that sits above it.
And so...
That's it. That's it, but I, I think, I think that works. Um,
and I think we actually might be able to get away without using permissions or
bouncer, Laravel permissions or bouncer, actually. Because we already have...
-Mm-hmm -... a process by which when a user logs
in, we look at all the security groups they're a part of, and we can inspect that
and assign permissions,
uh, it's basically just an array. It's just an array of permissions-
-Yeah -... which would be an enum cast
of, you know, w- of AD groups, AD security groups mapped to named permissions. And
we'll just cast them to an enum on that user and that's it.
-Yeah. -There's no, there's no need for, like,
-this one- -Yeah, I think-
... to many whatever, because we're not gonna do roles inside of the application.
Right. Yeah. I think if, if the permissions for your application are
coming from something like Active Directory, then there's, there's no need
to
-layer the package on top. -Agreed.
As long as you've got some way of translating those things into... You know,
I mean, you could d- dynamically register policies or whatever else, or, or gates
-and things like that- -Mm-hmm
... based on this. And then, whether you cache that, you know, for
24 hours, do you cache that just for the request, like do you use-
-It's... Yeah, just for the session -... it once or whatever?
-Yeah, it's just... Yep. -Yeah.
Yeah, and when they log in again, it does the check again. So it, it goes and talks
to AD and says give me the list of, uh, security groups they have.
-So you're not- -Yeah.
So how are you, how are you dealing with, like, changing in permissions if, if
-someone like- -Doesn't log in?
-... has a permission unassigned- -Yeah, right
-... while, like, during a session? -This is a good question. And, and this is-
Are you-
I don't have a good solution to this. This is a good, this is a good question to
ask.
So, wh- what I will say is like right now, and the way that they've had to do it,
like if they've had to add a permission is they'll add the permission and then
they'll ask the user to sign out and sign back in,
right? They sign out, they sign back in, when they sign back in-
-Yeah. Yeah, adding, adding is fine. -Yep.
Because someone, because someone wants that, I want extra things-
-Yes -... yeah, I'll do, do the work to sign out
-and sign back in. -Exactly. Now, the question is-
-But if you are having some permission- -... do we revoke that?
-... revoked. -Yeah. Yeah.
-Yeah. -Now, the way that we've got it set up
-right now- -Or, or if, or if it's a lease that it
-expires- -Yeah
... like it's gonna have to log you out somehow.
Yeah, so the way that we do it right now is, yeah, the thought is that we expire
the lease at like 6:00 AM. So at 6:00 AM on that day we say it should expire this
day, we revoke it. And if they haven't logged in that day, which it's very
unlikely that they have, then when they log in that day-
-Mm-hmm -... the permission will be revoked. Now,
in some weird case where we needed to revoke a permission for somebody
in the middle of the day, which I, I don't really see that happening. We don't
typically get requests to take permissions away. We get plenty of requests to add
permissions, but almost never. The only case I can think of where we say like we
would revoke permissions would be when somebody's getting terminated.
-You know, that happens. -Mm-hmm.
-But typically the way that that works is- -Yeah
... a manager will set a time to say, "Hey, at 1:00 we're gonna have the
conversation with this person, we need to terminate this user at 1:00." And so
they'll pull them in, the IT team schedules the termination for 1:00, they
then revoke that user's access and then by the time they get back to their machine,
it's locked and they can't get logged back in and it's fine. So-
Yeah.
I don't... It's, it's a, it's an interesting question to posit but I'm not
sure
that it's a critical component of what I'm hoping to accomplish. I, I don't-
-Yeah. -I don't know.
Yeah. And, and I assume in an organization like yours you'd have a risk register
somewhere, and these are the kind of questions that I sit there and I come up
with and I send it to the risk team, and they put it in the risk register and we
say, "Okay, we know about this but we don't care about it."
-Yeah, exactly. -And as long as it's in the risk register-
-Yes -... you know, it has been raised, it is,
you know, we've decided that it's not something that we're terribly concerned
-with, fine, but it's been noted. -Exactly. We mark it as an acceptable risk.
And it's better to have something on the
-risk register- -Yes.
Yeah, right, yeah, yeah. And it's better,
for those of you listening who are in, in smaller organizations or you're, you know,
on your own or whatever,
it's probably fine, you don't have to worry about it. But in, in big
organizations especially those that are, you know, ISO 27001 or their SOC 1, SOC 2,
whatever else, these are the kinds of things that it's, it is okay
to have these kinds of things sat on a risk register and you just say, "That's a
low risk, medium risk, it's acceptable," you know, we don't care about it but we,
b- but you still need to think about these kinds of things.
-Absolutely. -And then what you do with it is you just,
you decide, is it something that I need to, to put into code to protect against?
Or, is it okay to just, just to acknowledge that yes, that is something
that we are aware of, but we're not worried about it being an actual concern?
Yeah. I- so the two words that we typically use in those instances is that
we would say number one, it's a known, it's a known risk but it's a,
it's A,
it is an acceptable risk, and B, here is a compensating control.
Auditors love that phrase, a compensating control which just means we're aware of
this issue but we're solving it in a different way. So we would say the
compensating control is referenced user termination policy line 15, right? Where
it says, uh, you know, all user terminations will happen within 15 minutes
of a termination request or at the scheduled time requested by the manager.
And then you, you know, you basically reference, hey, here's the pla- place
where we say this is how we do it and this is why it's not a concern. That the
application handles it because our process handles it this way. Um, and so anyway,
those, those are good points to bring up, especially when you're trying to do those
things, SOC 1, SOC 2. If an auditor brings that up and you don't have a solution for
it like in code, i- if you have a solution for it in policy, um, then that's
usually good enough, so...
Yeah. Yeah.
-Well folks, that's all I've got. -Cool.
Michael, you got any... Uh, thanks for your help on that. I, I appreciate you
thinking through that with me. Um,
I think we're gonna move forward with that and I'll let you know kinda how things
go, uh, on that front. But, I think it'll be good. I think it's definitely gonna be
an improvement over what we've been doing.
-Yeah. Yeah, I think so. -Yeah. Yeah. So...
For sure.
All right my friend, Episode 179 of the North Meets South web podcast is in the
books. If you'd like to find show notes for this episode find them at
northmeetsouth.audio/179. If you'd like to talk to us on Twitter, on X, on all the
things, hit us up @michaeldurant, @jacobbennett or @northsouthaudio. And if
you liked the podcast we'd really appreciate it if you'd rate it up in your
podcatcher of choice, five stars would be absolutely incredible. Folks, we hope to
see you at Laracon, please say hello. We would love to talk to you in person. We
don't get to see any of you. Typically, for us this feels like speaking into the
void. It feels like nobody's listening to this ever until we get there and we hear
from all of you wonderful people. It's an encouragement every year to keep going-
-Oh -... and keep doing it, because...
I, I, I enjoy it. I think it's, it's good to know that people do listen but it's
-also a very bizarre experience. -Mm-hmm.
Because people know so much about you and you're like, "Hello person."
Oh, that's so funny.
-Yeah. -Don't let that deterr- d- don't, don't let
that deter you from doing it though, I love, love to meet the people. Um, and
it's been, you know, like I said, six years since I got to meet the people.
-Absolutely. -So. Except for those of you who are kind
and caring enough to come all the way down to Laracon AU.
One of these years I'm gonna get there folks.
All right everybody.
Till next time, we'll see you.