 We are deprecating rules by November 18, 2024. So let me show you how to migrate your Out Zero rules to Out Zero Actions. Hello everyone, my name is Karla and I'm a senior developer advocate here at Out Zero by OCTA. We recently announced a deprecation of Out Zero rules and hooks and we're focusing our attention on Out Zero Actions. But don't despair, this won't happen until November 18, 2024. So you have plenty of time to plan your migration strategy and to start migrating your rules. In this video, we're gonna focus exclusively on how to migrate Out Zero rules to Actions. We're gonna see some of the benefits of working with Actions, what limitations they have at the moment and then I'm gonna show you some conversion guidelines that you can take into account when starting your migration. And lastly, we're gonna go through some of the most common use cases and how to do that migration. We first introduce Out Zero rules as the first tool that allowed users to customize their authentication process. Rules are serverless code blocks that are executed right after a successful login but just before tokens are issued. Because we want to satisfy your extensibility needs, Out Zero has been working on a new tool called Out Zero Actions which cover most of the code-based customization needs. Let's talk a little bit about the benefits of using Out Zero Actions over our rules. Rules let you handle one authentication flow while Actions let you handle multiple flows. You have authentication, pre-imposed user registration, password changes, and so much more. Rules don't have an integrated version control system while Actions do. You can modify an action without affecting what's going on in production. You can create new versions and you can even go back to previous versions. Unlike rules, the Actions editors support code hints, isolated secret management, and even install all NPM packages. So overall, the developer experience is significantly improved. An important thing to remember is while rules and hooks are still available, they can live together with Actions. All you need to remember is that they will execute before Actions. There are some limitations that Actions have at the moment that you should keep in mind. With rules, you can share data with other rules in the pipeline by adding properties to the user and context objects. These properties are accessible in subsequent rules. In Actions, you can do this, although changes made in the user's main data can be accessed in subsequent Actions. Rules can modify some assertion or attributes while Actions can't. Rules have limited access to the out-serial management API and to the global and out-serial objects. Actions can't, but there's an alternative approach that I'll show you later in this video. If you wanna learn more about the limitations that Actions have at the moment, check the link in the description below. Let's take a look at some conversion guidelines you can use when migrating your out-serial rules to Actions. Out-serial rules allow you to customize your authentication flow. Because of this, when you're migrating existing rules to Actions, you need to associate the new Actions with the post-login trigger in the login flow. Now, I'll assume if you're watching this video, you probably already have some rules created and have an understanding of how they work and know how to create a new Action as well. If you need more information on rules and how to create new Actions, I'm gonna leave a link in the description below. Okay, so let's go to the out-serial dashboard and the rules section. As you see, I already have a few rules created and I want to migrate them with you during this video. Let's start with this last one called allow access during weekdays for a specific app. The name is pretty self-explanatory. If we look at the code, what this rule is doing is checking the name of the app. In this case, it's the app to check access to. Logging some stuff to the console for the sake of this tutorial and then is checking if the day is a Sunday or a Saturday. Then it's just simply not gonna allow you to use the application. So the first thing you need to do is to take the body of your rule function and move it to your action. So let's go to Actions. I already copied the body and I have an action created with the same name. Right now it's pretty empty because we're gonna be doing this together. So I'm gonna put the body here. And as you can see, this is not just a simple copy and paste and you're done. You actually have to make a few changes. So let's try to understand what these changes are. So the first thing that you're gonna notice is that the parameters in the function are different. With rules, we used to have a user, a context and a call by. And now in Actions, we only have an event and an API. So how can we translate the parameters from rules to the ones in Actions? So as a general rule, you can think that the read only properties in the user and context objects are going to be in the event object. So let's write these here. Read only props, user and object are gonna be in the event. Now any interaction with the running environment or if you wanna show a login error or modify the user metadata, that is going to be in the API object in the action. So anything related to the user data, you will find in the event.user object except for those attributes that are added by an identity provider or a custom database script. Something relevant to note here is that sometimes in rules, the user.app underscore metadata attribute could be undefined. This does not happen in action. The event.user.app underscore metadata is always present. Another thing you should keep in mind is that some of the variable names change names. So for example, in rules, you used to have a client ID and now we're talking about client underscore ID and so on. Now, if you notice, I purposely didn't talk about the callback parameter in rules. So let's talk a little bit about that now. In rules, you use the callback parameter to pass back the results of the processing. For example, in order to pass the control to the outside authentication process, which will probably rule the next rule, you should use the callback function and pass the user and the context object as it was done in our rule before. This is what you do when you want to stop the execution of this function. So whenever you want to stop the current logging process, you have to call the callback function with an error. If you did not have any errors, you can simply pass null as we did here. Now in actions, in case of failure, you can replace that instance of a callback function with an api.access.deny call. In case of success, you can simply put a return statement and sometimes you can even leave it blank because it will simply continue the execution until the end. Now let's summarize that a little bit. Basically, regarding the callback function, callback, basically if failure, then we want to do api.access.deny and if success, we want to do nothing or we can just return. So what I'm writing here is simply just a reminder to myself when I'm editing this code and hopefully it's useful to you as well as we go through the code. So since we already know how things change, what parameters map to, the name of some of the attributes type change and also how to replace the callback function, let's go ahead and edit this rule that we have here. So the first thing that we have is the context. We don't have a context anymore, but we do have an event and we need to get the client name from there. So a good thing about actions is that in the editor, you can actually test this and on the left side, you can see the event object. So before editing, I can either check this object and see how to access the client name or I can simply use the editor out of completion. So it would be event.client.name. And if you wanna double check because you don't trust me right now, we can see that in the event object, we have a client and a name. Right now we have a different name. So let's actually make sure that we use this name for testing purposes. All right, the next thing we should change is the user. So we no longer have a user and if I see my little notes here, it's in the event.user. So I'm gonna go with event.user and if you wanna double check again because again, you don't trust me. And the sad about that is event.user.email. So that's great. Then we get a few dates and here it's where I think they're a little bit interesting. So we have two places where we're using the callback function, one with an error and one just to stop the execution of the rule. So if we remember here, so if there is a failure, I can just call the API and deny access. So that would be api.access.deny. And you can put a message inside. Let's be consistent and use the exact same error message because we don't want our users to realize something has changed. This is looking promising. And then last but not least, you can do two things. You could write return here, but because this is the end of the function, it doesn't really make a difference. So we can just leave this as is. So if we wanna test this, we can go ahead and in the email, let's put a different email here. I'm gonna put Carla because that's my name and that way I'll know that this worked. We can click in run and see how this executes. It was successfully updated. And then here I can see the results, the snow error, which is good. I'm the one trying to access. Now, the reason why there's no error is because today is obviously not a Saturday or a Sunday because I'm working. But if, what day is today? So today is Friday. So if I wanted to test and see if I wanted to get an error, I can put this Friday. I can just force it to fail and try this again. And hopefully I'll get the error. I was freaking out for a moment and I was like, oh my God. But here you go. So we get an error saying that the app is now available during the week and the access is denied. So this is what we did to migrate our rule. Now, let's go ahead and see some real life use cases and migrate them together. So I'm here, my out zero dashboard again and I have these three use cases is to add a custom claim to a token, update the user metadata and redirect users. Let's start with the first one. If we look at this rule, what we have here is we have a namespace and we're adding more information to the ID token. So keeping in mind what we did before when we were migrating the previous rule, let's copy the body of the rule function go to our actions. And I don't have a previously created one because we're gonna do this together. So we're all in this together. Sorry. All right, so we're gonna click on build custom and call it add custom claim to a token. What is important here to remember is the trigger because rules execute during your authentication progress. It should be the login post login trigger. We're gonna create that and we're gonna put the content of our rule in here and we're gonna translate it into actions. So if you remember we said in the conversion guidelines that the read only properties of the context and the user objects were going to be mapped into the event object in the actions. But what about something like the ID token? If you think about it, the ID token is something that happens in the current environment that we're interacting with. So keeping that in mind, it means that it's probably in the API object. So let's inspect that API dot and we can see we have the ID token here. And as part of the ID token, we can actually check the functions and we have set custom claim, which is exactly what we want. And what we're gonna put here is, we're gonna interpolate the string name and excuse my JavaScript here. I think it's like this, namespace, which is the namespace of my app. And we're saying favorite color. And then we want to add the value and the value is gonna be the favorite color from the user metadata. So if you remember, we no longer have the user object, but we do have the event. So we can do event.user.usernamedata.favoritcolor. So this first line will then replace line 11. So we can probably get rid of that. And we're gonna do the same for the next claim, which is the preferred contact. So we're gonna do api.idtoken.setCustomClaim. And then in here, we're gonna interpolate the namespace variable that we defined earlier. Prefer contact, contact, not contract. And also pass from the user metadata, the preferred contact. I don't know why I'm saying contract, but it's contact. And we can also get rid of that. And now we have a callback with no error, meaning we can just get rid of this. And that is how we add a custom claim using our serial actions. Now let's go with another example. Let's go back to our rules that we have defined. And here I have update the user metadata. Let's take a look at that. And what this function is doing is reading from the user metadata, changing some values, changing the preferences, changing the font size, and then it's persistent the user metadata after the update. Oh well, it's actually updating it, right? So once again, we're gonna copy this code and create a new action, build a custom action. And this is going to be update users metadata in the login post-login trigger. We're gonna create that. And we have this empty function. We put our code here and indentate properly because otherwise it's driving me insane. Okay, so let's see how we can translate this code or even simplify it a little bit. If you see, we're accessing the user metadata and the preferences and we're kind of like initializing that. So here what we can do is we can create a constant and call it user preferences and assign the event the user metadata dot preferences. And just like that, we can get rid of these two lines. That's great. Well, the next thing we're gonna do is to change the font size. So because we already have the user preferences here, we can just replace this part and just change the font size like that. The next thing we need to do is to persist the user metadata. So what we're gonna do is here we're calling the out zero users update user metadata method. This actually makes an HTTP code to the out zero management API every time you invoke it. So what we're gonna do is we're gonna do API dot user dot set user metadata, not app metadata, user metadata. What we're gonna persist is going to be the preferences and I'm gonna pass the user preferences object that we were just editing. And just like that, we can simplify this code and get rid of all of these callbacks. Not because this is the end of the function, we don't have to put a return or anything. And another thing to keep in mind is that as I said earlier, every time you call the out zero dot users dot set user metadata, that would end up in an HTTP request to the out zero management API. In actions, all the invocations that you make to the API user set user metadata will result in one single API call. And this will contribute to mitigating the risk of rate limit errors. Once that we have this rule migrated, let's go back to our rules and migrate the last one. This is another common use case. It is a redirect users rule. And this rule is meant to be used when you want to redirect the user to a different page to complete the loading process. Now this rule was drawn twice, before the redirection and on the response. Now typically you need to put the code of handling the redirection and the response in the same rule. And also you need to manually check which of these protocols is eligible for a user redirect. So let's go ahead and translate this rule. Once again, we're going to copy everything to to to go to our actions and create a new one. So we're going to build our new rule redirect users, same trigger login, post login. You're going to click on create. Now we haven't really covered this part yet, but if you notice in line 18, we have a function that is commented. So we're going to uncomment that. And the function is called on continue post login. And if we use our little editor and read the description, this is the handle that will be invoked when this action is resuming after an external redirect. And if you think about it, we were talking about this rule being executed before the redirection and on the response. So by putting part of the code in this function, we're going to simplify it a lot. So let's put the code here and see how we can do this. So if we look at this function, we see we have a few conditions going on. The first one is we're checking about the protocol, if it's a redirect callback or if it's off to password and so on and so forth. But we're also checking if the user has already been redirected or not. And actions probably can help us simplify this big condition. So let's check how we can do that. The first thing we can do is let's start with the simple one, which is checking if they haven't been redirected. So that is very, very similar, but instead of using both user is event.user. So we're going to do if the user hasn't been redirected and here's where the interesting part comes because in actions the api.redirect.canRedirect method actually takes care of checking if the protocol is eligible for a redirect. So basically if the user hasn't been redirected and the protocol allows it, we're going to redirect them right. So the way we write this with actions is we're going to say api.redirect.sendUser2 and we want to send the user to this URL right here. So we're going to copy that and put it here, like so. So we've already taken care or simplified all of this part here. Well, most of it if you think about it, definitely the redirect here, this is done. So we can get rid of it. The only thing we haven't done yet is to say that the user has been redirected but this should happen after the fact. So let's go ahead and use the new function that we discovered just now. So instead of doing it here in the onExecutePostLogin function, we're going to go to the onContinuePostLogin. So what we're going to do here is we're going to say api.user.setUpMetadata and we're going to say, we're going to use the same name was redirected and we're going to set that to true. With that, we can also get rid of this part of the code and this ends up pretty, pretty simplified. If you want to learn more about redirection on actions, I'm also linking that in the description below. Now with that, if we go back to our custom actions, that means we've already migrated our four rules into our four actions. Now that we have seen the conversion guidelines and that we've migrated some of the common use cases of rules into actions, you should have a better understanding of how the code differs from one to the other. But this is not the only thing that you should care about. You should also have a strategy to start your migration and avoid issues in production. Once you have a strategy in place and you have migrated your rules to actions, then you can proceed to activate your action and deactivate your rule. Just keep in mind that this task must be quickly in succession. Depending on the order, there might be a small period of time when both the action and rule are running together or neither are running. Also something to keep in mind is because rules run before deployed actions, something you can do is to start at the end of your rules pipeline and work backwards so you can keep some logic in your rules and test other logic in your actions. So in this video, you learned about how to migrate rules into our zero actions. We talked about the conversion guidelines and saw some of the most common use cases. Now let me know if you enjoyed this video and if you have any questions, leave it in the comments below. Thanks for watching.