Hey there Psych2Go family, welcome back. We at Psych2Go look forward to your continued love and support. With that said, let's begin. A lot of us feel like we don't deserve to have our dreams come true or have good things happen to us. And sometimes no matter how far we've made it or how much we've already accomplished, we still don't feel content. Why is that? The answer isn't an easy one. Most likely, it's when we grapple with feelings of self-loathing. Self-loathing is defined as hatred for oneself that often manifests as anger, self-sabotage, a negative view of oneself, and low self-esteem. It's important for a person to be aware of their feelings and attitudes towards themselves so they can start to change for the better. Here are seven signs you may be suffering from self-loathing and just don't know it. 1. You tear yourself down. Self-hate makes you your own worst critic. Keeping an eye on your shortcomings is a good thing, but not allowing yourself from to breathe stems from an immense dislike for your current self. You think extremely harsh things about yourself and indulge in self-pity a lot. So much that tearing yourself down has become a daily habit for you.  You're quick to blame yourself whenever something goes wrong, even if it's not your fault. You never commend yourself for a job well done, but rather criticize yourself for even the tiniest of mistakes.  2. You feel insecure around others. If you find that other people make you feel insecure about yourself a lot, it might be time to ask yourself why. Most likely it's because you're constantly comparing yourself to them and feeling like you'll never be able to measure up no matter what you do. Subjecting yourself to this kind of harsh judgment is a definite sign that you hate yourself. When you look at someone else, you always focus on all the things that they have that you don't. And it makes you ungrateful for all the good things you do have. You can't help but feel bad about yourself whenever you're around someone who's happy, confident, smart, attractive, or successful. 3. You neglect your self-care. If you want your loved ones to be happy and taken care of, chances are you probably answered yes right away because when you love someone, you want what's best for them. So if you really loved yourself, you'd want that for you too. This is why neglecting your self-care is a form of self-hatred. You don't sleep well, you're not eating right, you don't exercise, you don't try to look nice for yourself, and you don't do things that make you happy. It's not that you don't have the time or can't be bothered enough, it's more about refusing yourself to pampering because of a deep-seated grudge with yourself. Since your insides are at war with you, it only seems right to let yourself show it outwardly as well. So when you look in the mirror, all you see is a haggard reflection, unworthy of love, and that's how you like it. 4. You don't let yourself be happy. You're a pessimist who's quick at finding the negative aspect in every situation. You're wary of compliments or praise because it seems mocking. You don't see yourself in a positive light and refuse to believe what others say. However, you do take their criticism to heart because it reinforces your view of yourself. You're not comfortable letting other people help as you believe your troubles are yours alone and you deserve them.  You resent the way you are and deprive yourself from anything, even remotely akin to delight. These are just a few of the ways that you deny yourself happiness, perhaps even unknowingly, as you fester in your own self-hatred. 5. You isolate yourself from others. You struggle to maintain relationships with others because you feel like you don't deserve their love. Often you feel their attention and love is a burden for you. You don't consider yourself good enough to remain in the circle.   You feel guilty for hanging out with them because you believe your presence is an intrusion upon them, and you're holding them back. Your inability to love yourself makes you unwilling to accept love from others as well. As a result, you isolate yourself to refrain from inconveniencing others with your presence. 6. You put on a facade for others. You're one way when you're by yourself, and then another when you're around other people.   You feel ashamed of your true self and you think that no one will ever be able to accept you, so you'd rather pretend to be someone you're not. 7. You're afraid to dream big. Having ambition and dreaming something big for yourself scares you. You smother your own hopes and aspirations because you think you'll never be able to achieve them, so what's the point?  The possibility of failure and rejection terrifies you.  You deny yourself opportunities to grow and have new experiences because you don't believe in yourself. Your insecurities make it hard for you to see your capabilities and you can allow yourself to succeed. We all have a lot of self-destructive behaviors that are toxic for our mental health and emotional well-being. So many of us struggle with feelings of insecurity, emptiness and worthlessness that it can sometimes lead us to hating ourselves. Being more aware of your self-hatred makes it easier for you to overcome it. And with time, patience, support and dedication, you can learn to love yourself and live a happier, healthier life. Did these points remind you of someone? Maybe yourself? Can you now see where such behavior stems from and why? Did these points make it easier for you to name your emotions and behaviors? Please let us know in the comments below. Also share this video with anyone you think might benefit from it. And we'll see you in the next one.


Medicine is a combination of art and science. We want to elevate the quality of treatment for our patient. Evidence is crucial, so the clinic and the research institute work hand in hand. We have a continuous pursuit of innovation, less time for recovery, less pain for the patient. It's amazing how these efforts benefit the patient. At the Stem and Clinic and Stem and Philoponic Research Institute, we treat the athlete in all of us.


It's time that we know the word like never before. And I mean be established on the foundations of the word truly, deeply, sincerely. Because think of all that's coming against us in the culture today, in the nations. There are all these different ideas and philosophies and it seems like there's a lot of confusion and a lot of people are walking on sinking sand. They have no firm foundation by which they can gain their bearings. So it's time to know the word of God like never before. It's time to read it like never before. It's time to memorize it like never before and declare it like never before. It's time to go deeper.


does this all work? So over there on the left-hand side, Okta is the authorization server, and Okta has access policies. And the purpose of the access policies are to decide if you issue a token for an application. And then how long is that token going to be valid for? The client applications are going to request those tokens from Okta, the authorization server. Then they're going to use those tokens in order to access the resources. So over there on the right-hand side, we have A, B, and C are different APIs which are protected, you know, with OAuth. And so we're going to need to present those access tokens in order to access those endpoints. Now in Okta, it's a little bit complicated. And the reason is, is that for a given Okta org, you will see, or it has the multiple authorization servers. So your Okta org is essentially not just one authorization server, but multiples, okay? Now we have terminology for these. There's the org or the base authorization server. This one is for single sign-on. So when you think about doing single sign-on with OpenID Connect, this authorization server, which can be found at your unique domain, yourcompany.okta.com slash OAuth2 slash V1, this one's all about requesting ID tokens for the purpose of doing federated authentication, in other words single sign-on. Now Okta also has another authorization server that we provide to our customers who have bought single sign-on. And that one's called the default authorization server. The way I want you to think of this one is think of it as a, you get the first one free. So for people who have not purchased API access management, you can try it out in any of your orgs using the default authorization server. Notice the URL is slightly different. It's OAuth2 slash default slash V1. You get one of these and what you can do is you can try out with one of your APIs using API access, even though you haven't purchased that product. The custom authorization servers is for our customers who have API access management, the product. And now they want to do a high degree of customization to really get this thing to do what they want it to do. So in this case, what happens is you define a custom authorization server for each resource server that you want your client applications to access. You can define as many of these as you want. And essentially what we do is we generate a unique ID for each of these authorization servers. Now let's now talk about access tokens. An access token is a implementation of a JSON web token. And so the idea here is that a JSON web token is a couple of JSON objects with a bunch of key value pairs. And these are called claims. And in these claims, we have identity information and access information that's relevant to these requests. So let me walk you through it. ISS is a claim that stands for the issuer. So this is the URI of the specific authorization server in your octa org that generated this token. AUD stands for audience. This is the intended recipient of the access token. So in our case, it's the resource server, typically what people do is they use the URI of the server. But it can just be any string identifier that you create. It does not have to be in that format. There is an expiration. This identifies when the token will expire. Very important. You don't want to accept a token that is expired. The CID is the identifier for the client application. So in this case, CID, when you generate an application in octa that is of type, open ID connect or OAuth, octa will generate a unique client ID associated with that. And what you would do is you can then verify that client ID in the access token to identify what client application is this token intended to be used with. There's UID, which is user ID. This is the user associated with this request. And then scp stands for scopes. These are the permissions contained within this token. So I talked about this previously when we talked about the meetup example. Remember I said that the token that was issued to meetup had the ability to perform write operations, but it did not have the ability to perform read operations. So in this case, this token has the ability to both read and create promos, but maybe it's missing the permission, let's say, to delete promos. It does not have that capability. And then the subject is the who. You'll notice that it's matching the UID up above. And the reason is that in this case, this is a part of a user oriented grant within OAuth. You do have the capability to do system to system that does not involve a user in which case the UID would not match the subject. In that case, the sub would be equal to the application ID, the client ID. So for those of you who have attended the previous session I did on OpenIDConnect, we had our ID tokens that we were working with for the purpose of single sign-on. They also had an audience and an issuer and a subject. Now the key differences that you'll notice here is that when you're talking about an ID token, notice that the audience for the ID token is the application, the client application, so the relying party's client ID. As opposed to an access token, the audience for that is the resource server, so the intended recipient. The thing that we're accessing is the API, not the app. The issuer is the same. At the end of the day, this is being issued by an authorization server configured Octa. The subject is in an ID token as the end user's client ID. In the case of the subject, it's basically the same in an access token. And then there's an additional parameter, which is the CID that stands for the client ID of the client app. Essentially, you can think of this, the audience in the ID token would match the CID claim in the access token. Those would be the same values. All right, so let's do a quick little quiz here, test your knowledge. So who's the actor? So taking a look here, we have our resource owner, A, B, C, or D. What do you think best defines the resource owner? All right, the resource owner wants an app to do something for him or her. What about the resource server? What best defines the resource server? B, C, or D? So the resource server has APIs that will be accessed on behalf of that resource owner. The client application, so B or D, the client application accesses the APIs on the resource server on behalf of a user, which means the authorization server is going to grant access in the form of tokens. All right, a big thing you need to think about when you think about working with API access management and custom authorization servers is how are we going to approach configuring and setting these up? So I mentioned that in a given octa org that uses API access management, you can have multiple custom authorization servers. Well, how and why would you configure these? Custom authorization servers mean that you can have a custom audience. You can define custom scopes and custom claim data that go in your ID tokens and your access tokens. They support five different ways for obtaining tokens. We refer to these as grants or flows. And so just to quickly run through them, the authorization code flow, the authorization code flow with Pixie, the implicit flow, the password flow, and then the client credentials flow. So think of this as, for different application architectures, different mechanisms to obtain the tokens. So different mechanisms that the client app uses to obtain the tokens from the authorization server. And then finally, a custom authorization server gives you the ability to configure what are called access policies. And that determines your rules, your security rules, about when and if you will generate a token, issue a token, for this request. All right. So how many custom authorization servers would you create? What you want to do is you want to identify resource servers as a logical collection of related APIs. We'll look at an example, but it's not necessarily something like for every host. I create a resource server. It's not about where the app lives. It's a logical set of APIs. However you group those APIs, you would consider those to be a resource server. What you're going to do is associated with each of these logical collections of APIs, you're going to define an associated authorization server. Notice it has a unique audience which identifies that resource server. And then a set of custom scopes, which are permissions and custom claims, which are pieces of data that would be in the access tokens that are being sent to the resource server when we request whatever that service is. So let me give you an example. In this case, we have an example in which the organization that's setting up API access management has a bunch of order management APIs and a bunch of sales quoting APIs. So they've created their own set of REST APIs for these two purposes. What they might do then is by identifying these two collections of API endpoints as resource servers, they would define a custom authorize one custom authorization server for each of these. The first one is called orders. The second one is called quotes. The value that they would enter in for the audience, it doesn't need to be a URI, but that's what we're doing. It is the recommended naming convention for a format for the audience. So HPS orders and HPS quotes. And then we're going to define custom scopes and custom claims associated with each of these resource servers. Under the custom scopes, we have orders, read, create, update, and delete. So the classic CRUD operations, create, read, update, delete. We also have a special permission, orders admin for administrative types of operations. And then there's one that's very specific to orders, orders expedite. So let's say that we have a customer who maybe, I don't know, they're down, they need a part as quickly as possible, something along those lines. And so this is a special permission that's maybe only given out to vice presidents or directors or whoever where they can say, all right, this order needs to be expedited. And so they could be granted this scope. And they would have that permission when they perform that API call. Over on the quoting side, once again, we have CRUD, create, read, update, and delete. We also have a special admin scope. And then notice we have one called quotes discount. Once again, very business oriented. So let's say only a VP can approve of a deep discount. So in this case, we could use that as a part of our customs codes. In addition, we could set up custom claims. Now, the key thing here is that here we have things like a manager ID, admin roles, and so on. The thing to keep in mind is that this should be related to authorization logic. Cost center is probably not the best thing to include in here. It really should be oriented towards things like permissions or additional role kind of information that is used as a part of the, maybe the visibility. So if I do a query, I would say I have read permission. I don't necessarily have the ability to read all orders or quotes. Maybe there's something that finds that more on a row level basis. Now that I've defined the authorization servers, I also need to define what are called access policies for each of these authorization servers. So in this case, let's say that I have one of my authorization servers, I'm going to define two access policies. Now the way that access policies work is that access policies are associated with one, many, or all of your client applications. So in this case, what we've done is we've created two access policies. One for internal apps, it's going to have its own set of rules. And another one for external apps that, let's say, our customers and partners use. So in this case, let's once again map this to our real role use case. So in this case, we're talking about our order management set of applications. So the client applications, let's say we have a sales opportunity converter. So the sales rep has gone out, they've closed the deal, and now they're going to convert the opportunity into an order. So there's our front office order application. And then on the back office, the manufacturing order management application, in this case, people actually fulfill the order, this is the app that they use for that. And then in our external apps, maybe we have another app called the customer order viewer app. And this application is used by customers and partners to track their orders. Now associated with each of these access policies, one for internal and the other for external, you're going to create what are called access rules associated with them. Now before I do that and talk about access rules, I just want to talk about how we would model this. So if we have our two client apps and our two resource servers, what you'd end up doing is because you have two resource servers, you would, because you have two resource servers, you would define two custom authorization servers associated with those collections of APIs. Now because resource server A is being accessed by two applications, that means you may or may not, you could have one access policy, but you might also have two access policies. So notice we have an access policy for client app one and an access policy for client app two. In the case of the resource server B, in this case, there's only one access policy because there's only one client app that's accessing it. So going back to here, you've created the access policies according to the client apps accessing your APIs. Now what we're going to do is we're going to define access rules, which determine if you issue a token and how long that token will last. Access rules, as I said, determine if we generate the token and it's lifetime, how long it's going to last. This is based on three pieces of information. What flow are you using to obtain the token? Who are you based on group membership or explicitly referencing you directly as a user? And what scopes are you requesting, which really determine what do you ultimately want to do with the access token? What Octa does is Octa evaluates the rules in the order they're listed. So in this case, what we do is we have a customer rule, an employee rule, and a manager rule. What we would do is we would first evaluate the customer rule. In this case, this one is only giving read permissions for those orders. It doesn't matter who you are when you request it. And in this case, we're using the implicit flow. We will generate a token that will last one full day. Now, let's say that we request not only the ability to read orders, but the ability to create orders. In this case, what's going to happen with the employee rule, or let me actually backtrack, the customer rule will not apply. By requesting both read and create, it's going to say, all right, this is beyond my allowed scopes. So Octa is going to move on to the second rule and evaluate that. In the employee rule, you could request read, create, update, and delete. You must be a member of the factory group. So in this case, there's some group in Octa. In fact, it could be sourced from another location, so AD or an LDAP directory. And then with the flows, it doesn't matter what flow you use, but because this token has additional scopes, the timeout for the token is only two hours. Now, let's say you're that vice president. You have the ability to expedite orders. In this case, if you request the order's expedite scope, neither the customer rule nor the employee rule will apply. You must meet or be a subset of all of the conditions in the rule. So by requesting the expedite, that would take us to rule number three. The user must be a member of the manager group. In this case, the strongest flow you can use from a security standpoint is the authorization code flow. And then the timeout for the token will be very short-lived, only 20 minutes. Now, if you make a request that doesn't meet any of these rules, that means the token request is denied. Octa will block the request that's coming in. It's outside of the scope, essentially, of your policies and rules. So if we go back to our modeling of the Octa entities to the OAuth entities, so what we would do is we define a custom authorization server for each of our resource servers. And access policy is associated with the different client apps that are accessing us. And then for each access policy, we would create one or many rules that decide if we're going to generate or issue a token and for how long that token will last. A very important part of OAuth and security is validating the access tokens. There's really the first four here are the ones that must be done. You've got to validate the digital signature. Octa provides a keys endpoint to validate the digital signature using a public key and standard algorithms. You need to validate that the issuer of the token is your Octa org and specifically that custom authorization server that you defined. You need to verify that the audience matches your identifier for your resource server and that the token is not yet expired. Optionally, you can also check the client ID to make sure that you're only being accessed by certain clients. All right. I'm going to do another quiz. Once again, let's apply what we just learned. So we have our OAuth actor on the left-hand side and the access token claim. So when you think about the authorization server, what claim in the access token represents the authorization server? Is it A, B, C or D? So think about this one a little bit and then make your best guess. All right. So the correct answer here is C, the issuer. The authorization server issues the tokens. So the client application, A, B or D, the client application is represented by CID, the client ID. The resource server is represented by B or D. The resource server is represented by the AUD. In other words, the resource server, the APIs are the audience of the token, the intended recipient of the token, which means the resource owner is represented by a sub, a subject that's basically the who is a part of this request. All right. What I'm going to do is at this point, I'm going to do a demo of the hands-on labs. Now, you're going to get a chance to do this on your own, okay? So we're going to give you the opportunity to access a virtual machine. We're going to give you the opportunity to access an octa.org. There's essentially a set of credentials. If you want, you can go out to this octaes.com, secure API lab guide and download this right now. But I'm going to first do a demo. So I'd like you to watch what we're going to be doing and just think about it.  All right. So let me do this. Let me jump out of here and let me go into my virtual machine. When you go to that URL, we'll be posting it later. Just so you know, don't worry about it. We'll put it in the chat window. You're going to be able to download a set of lab instructions in order to do these hands-on labs. Sorry, let me scroll down here. So the first thing that I'm going to do is I'm going to navigate out to my virtual machine at octa.instructorled.training. Now, later on when we do the labs, each of you will be assigned a unique access code. And so I'm going to use my unique assigned access code. And what I'm going to do is go in here. Now, I already went in here. It's going to prompt you to enter in your name and just enter in your name. And then also you're going to need to click to consent to the policy. It's also going to offer you the opportunity to protect your VM with a password. No need to do that. So if it challenges you to create a password or one it does, don't do that. I'm going to go in here. By default, we're logging in as rtabin. I'm going to go in here and select other user. Once again, this is all in the instructions. And I'm going to log in as administrator and then train me 4321. This is in the instructions. Admin, administrator, not that. All right, administrator. And so, like I said, train me 4321. The password is in the instructions. All right. Now that I'm in or almost in, the next thing that we're going to do is we're going to go out here. Just takes a while to render. There we go. All right. We're going to have you create a directory. So I'm going to go out here, go to the root directory, mkdir, files. And once I've done that, I'm now going to download the files that I need in order to do these, it's basically the starter code to do these labs. All right. The location that we're going to send you when we do this is going to be, you basically have a octaeducationservices.com slash. And then we're going to go to dev lab code. And so this is going to give me access to a zip file. I'm simply going to go to the upper right hand corner, click on the download icon, download this to my downloads folder. So here under downloads, I'm going to take this devday.zip file. I'm going to extract it. So let's see here. There it all, extract all. And what I'm going to do is go in here and select the C drive and then the class files folder that I just created. All right. So now that I've done that, let me see if this, all right. Unfortunately, we have a little issue here, which is the devday creates a devday folder based on the name of the file. Let me just do this. I get, you don't really need to do this. There's probably, I'm probably doing something wrong the way I'm extracting these, but anyways, I'm going to move these up here in order to put them in the top folder. All right. So now that I've done that, I'm going to log into my octa.org. So back here, I'm going to go to octane218000.octapreview.com, training 4321. All right. I'm going to log into this org. This is the first time I'm doing this, so it's going to prompt me for, a lot of you have probably done this before, forgot password question, security image. I'm going to click on create my account. And here we go. All right.  Okay. So in octa, here under applications, I click on applications. I'm going to add a new application, but I'm not going to use the octa integration network. This is a custom application. So I'm going to create, click create new app. In our case, it's a single page app. So I'm going to select spa and then click create. The name of this application is going to be the promos app. I'm going to add a redirect URI, HTTP localhost 080 slash token callback, like so. All right. This is essentially a URL in the client application that's going to receive something called a temporary authorization code that is then used to request the access token. I'm now going to click on save. And what I'm going to do is octa is going to generate a client ID for me. Here is the generated client ID, the identifier for my client application. Promos app client ID, paste that in like so. Okay. All right. There's another thing we need to do. We need to set up something called a trusted origin. It's here under security and API.  And what this does, by adding this trusted origin, I'm going to enable something called cores cross origin resource sharing. What this does is it allows an application that is being or I should say a web page that's being delivered from the domain localhost 8080. It allows web pages delivered from this domain to do an Ajax call to my octa org. So this is essentially an allow list. It's a grant list that allows this domain to do Ajax calls to my octa org. By default, browsers block that. It's called the same origin policy. And so by configuring this, we create an exception to that rule. And so when we use the office DK for JavaScript to do this API, these set of API calls, this will allow those calls to go through. All right. The next thing I'm going to do is I'm going to define a custom authorization server since I'm right here under API. So I'm going to click on authorization servers. Now in our example, we're going to be working with the promos API. All right. And so I'm going to go in. First of all, here's the default authorization server. We're not going to use that one. I'm going to define my own custom authorization server. And it's called the promos API on server. Okay. Our promos were an ice cream company. At least we were pretend one. And so we create coupons called promotions. And so we have a set of APIs around those coupons. Our audience in my case, we're going to be running our resource server on port 5000. And then the description protects the promos rest API. I have a problem with my capitals, but that's okay. All right. Now what oct is going to do is oct is going to generate a unique ID for this authorization server. All right. So there's another piece of information that I need to collect here, which is the issuer URI. So I'm going to copy this value. And I'm going to go back into here and indicate that this is the issuer URI. Paste that in. Because later on, I'm going to use that when I'm configuring my resource server. Also actually my client app too. They both need to know about this destination. All right. So this is the identifier for my resource server. And this is the identifier for my authorization server. All right. Now what I'm going to do is I'm going to go in and define some custom scopes. So key thing here is that we need to create custom scopes because we have our own proprietary APIs that do our own unique things. So I'm going to click on create scope. And the first one I'm going to do is the name of this will be promos read.  That's okay. Read. Yeah. That's second uppercase character. All right. The display phrase is essentially used in the consent screen. So this should be something that is understandable to your end users, the people using this application. And the description is additional information to further describe what this, you know, what this permission is granting. So I'm going to click on create. Uh, you can also say this requires consent. Uh, default scope means don't have to request it, but we'll return it and then include in public metadata is, uh, there's a discovery document out there in JSON, which describes the capabilities. Do we want to publish this publicly? So I'm going to create that one and then create a second one called promos create promos. And so this one is create new promos via API. And once again, we'll leave the rest of these unchecked. There we go. All right. So you definitely want to have well thought out, well thought out display names and descriptions for what your APIs are going to do. Uh, under claims, we're not going to do this, but you could define, uh, additional data that goes into your access tokens for that matter, your ID tokens too. It can be one of two types. Let me just click on add claim just so you understand. Within here, you can add it to either the access token or the open ID connect ID token. And you can reference using Octa's expression language. You can reference things on the Octa user profile or the application user profile. And so imagine we might create something called DEP and it would reference, let's say the department attribute on the Octa profile for the whoever the current user is. Okay. In addition, uh, to the user profile, we also have references to groups. And so this would be include the groups that the current user is a member of in the, uh, basically in the, uh, uh, token. All right, we're not going to do that though. I'm going to move on now to the access policies. So I'm going to define an access policy here. When you define an access policy, you're going to give it a name, promos app policy, and then the description. So in this case, this access policy is specific to the promos app. So you can imagine you have multiple, uh, different applications accessing your APIs. You might create policies for each application. So I'm now going to click on create policy. And then I'm going to define an, uh, a rule that you can have multiple rules in your access policies. So much like we saw with customers, employees and managers back on our slides. So I'm going to add a rule and this one is going to be called the read only promos API. And what I'm going to do is I'm going to limit this to just working with the authorization code flow. In our case, the authorization code flow with pixie. And I'm going to say when you could, you could, you could say, I want to apply logic that the user must be a member of a group or a specific user. And then, uh, you can also say, I'm not going to actually do that. I'm going to go in here and say, all right, and then the scope's being requested. So I'm going to do, uh, open ID, which is for the ID token. This really doesn't apply to OAuth email. Once again, for the ID token profile for the ID token again. And now here's the key part. I'm going to enter in promos read. So in this case, when they, uh, request the ability to read perform read operations on our promos API, uh, that's going to make this rule apply. All right. Uh, I'm now going to go down here. Let me just show you the fact that you can define the lifetime of the token. So I could go down here and say, you know what, I want this to last for 45 minutes, something along those lines. So you can modify this to be something, uh, you know, that, uh, in general, the more, the more the permissions of the token, the shorter you want the time out to be. Okay. I'm going to click on create rule. And now, uh, I need to update my application to request the token and then to, uh, use it and also to protect my resource server. All right. So I'm going to go back here to my command prompt window and I'm going to go into class files and go to the day and then promos. And we're going to go to the spa API client, not the promo spa, this promo spa API client. Make sure you go to that folder. I'm going to do an npm install to install all the necessary dependent libraries. Now, uh, as the instructions say, we're going to have you move on to the next lab. This is going to take a while. So to save time, we're just going to start working on the resource server to open up a new command prompt. What you do is you right click on the existing command prompt, select command prompt. And then what you do is we're now going to do this. We're going to go to class files again, dev day, and then the promos resource server folder this time. And once again, I'm going to do an npm install and install all the necessary libraries. This one should not take nearly as long as the client application. So what we'll do is we'll just let this run. Cool. Now what I'm going to do is, uh, we're going to use Octa's JWT verifier. So it is a library for JavaScript. We have ones for additional languages. And what this is used is to perform those checks, check the digital signature, the issuer, the audience, and the expiration to validate that the token is a valid token. And then also it hasn't expired. All right. So I'm going to do an npm install and then do at octa slash JWT hyphen verifier, like so. And then we're going to use 2.0.1 and hyphen save. All right. This one will not take long at all. All right. Now, uh, I'm going to launch Adam. And what I'm going to do is just, uh, walk you through the code. So walk you through the, well, working with the client app and the resource server. So I'm going to go in here to add a project folder. And what I'm going to do is go to class files, select dev day, and then click on the select folder button. Now there's, uh, the two folders that we're going to be working on are the promos resource server and the promos, uh, spa API client. Now in the promos resource server, I just want to point out that there's two key files in here. The setup controller, what this one is, is this one is the, essentially the API endpoints that can be called. So this is using Node.js. And so down here we have, for instance, this will be get called on a get. Uh, if we keep going down, there's another get. This one is essentially a create operation associated with an HP post. There's also a delete down there for an HP delete operation. Uh, and so these are the different endpoints that we can call. And what we're going to do later on is we're going to update this to require the, uh, the tokens. Over in the security utils, the purpose of this one is to have the logic, which uses the JWT verifier, um, to then check the authenticity of the data in the access token that's being passed. All right. So in the security utils, the first thing we're going to do is we have a reference to the, uh, class associated with the JWT verifier. One of the things you can do to toggle comments on or off is just do a control forward slash. Uh, the next thing I'm going to do is on line nine, I'm going to update the audience. So this needs to match. I'm going to enter in the audience value local host port 5000. Okay. Uh, the key thing that this needs to match if we go back to here, go back to my authorization server. There's the audience, right? That must match. And so that's what I'm doing there. Okay. All right. Uh, we're also going to uncomment lines 17 through 24. Let me uncomment those. Uh, this is going to instantiate the JWT verifier and we're setting up a bunch of properties such as the issuer URI. All right. So what I'm going to do is I'm going to go back to my notepad and I'm going to copy the issuer URI, do a control C and then go in and do a control V right here. Like so. All right. The client ID, uh, is something that we're going to pull from a command line, uh, environment variable. And then later on, uh, once we have, so the audience was declared up here, we're also going to be working with the scopes on a case by case basis on an individual endpoint basis. Uh, the other thing that we're going to do is we're going to make available by uncommenting lines 27 through 35. This is the function that we'll call when the API endpoint is, uh, called in order to validate the access token that was passed. All right. So now what I'm going to do is I'm going to click on save. And now I'm going to go back to the setup controller and I'm going to turn on security for the, uh, promos read endpoint. So right here, I have a, uh, essentially, uh, this, uh, function call over to the, the, um, uh, check that the access token being passed is valid. And also this is the key thing is being presented or has present the promos read scope. All right. So this is, uh, our rest endpoint for getting promos. And in order to get promos, you must have the scope promos read in the access token as a part of the request. Okay. All right. All right. Um, all right. So now that I've done that, let me just save the file. And then what I'm going to do is start the resource server. So I'm going to go back here to my, basically my windows. Uh, this is the one that has resource server. So make sure that you go to the, the one that has the current directory set to resource server, not the, the single page out. I'm going to set the octa client ID, oops, ID equal to, and this is where I'm going to go back in a notepad. And I'm going to grab the client ID and what I'm going to do is I'm going to paste that value in like so. So I'm going to set up that environment variable and then what I'm going to do and then start. Yes. And there we go. I'm going to start up, uh, start up node and now my API server is going to be available and callable. Okay. All right. That's all done. So now I'm going to move on to the next part of this, which is to update the client application to request the tokens and then to add them to the outbound request. All right. So over here, back in Adam, I'm going to collapse the resource server folder and now focus on the, the spa API client. Let me actually close down these windows here. All right. Uh, in here, we're going to have you navigate to the off folder in the index.js. This is going to need to get updated right here where it says your org URL. In my case, I'm 218. It's nice and easy for me. I'm 0, 0, 0. For the authorization server URL, this is how we find your, you, this custom authorization server that we defined. I'm going to go in here and this is where it gets a little bit tricky. I need to copy the ID of the resource server right there. So I'm going to copy the ID of the resource server. It starts with AUS, logically, right? And so I'm going to update that so I have my unique authorization server ID. Okay. All right. I'm going to now save the file. Okay. And then I'm going to go into my first window, which is where I have the single page app. Once again, I'm going to do set octa client ID equal to and what I'm going to do is I'm going to paste in this value like so and set that environment variable. And then I'm going to do an mtm start, start up the web server. All right. When I test this, I just want to point out that when I test this, it's not going to work. And the reason it should fail is that I'm not requesting the proper scope. I'm not requesting promo's read. And then the second thing that's going wrong is not only am I not requesting the proper scope, down at the very bottom, we have this get off header function, which right now isn't doing anything. We're going to need to make sure that we add the access token that we get from octa to the outbound authorization header when we do our request over to our resource server. All right. So this is going to fail, but that's okay. All right. So what I'm going to do is I'm going to go over here into the Chrome dev tools and take a look at what happens when I run this. All right. So now that I have this open, I'm going to go here to my profile. Now, I'm already logged into octa, so it's not going to prompt me to authenticate again. I'm going to go in here and click on my profile. Let's see here. What did I do wrong? Authorize client ID, code challenge get. Let's see here. All right. I'm going to do a little debugging. What did I do wrong? Code challenge. Pretty sure my octane 218. Yes, 218. OctaPrivy.com. My ID looks good. Client ID. Oh, wait a minute. All right. I see what I did. All right. So here's my problem. My client ID in my memory or in the clipboard buffer, I basically had my authorization server ID, not my client ID. So I took, I needed to select this one. All right. So this is a fix I can solve. All right. So I'm going to go to a control C. And what I'm going to do is let's try this again. Set. Yep. There's the problem. All right. It starts with AUS. It should not start with AUS. So I'm going to go in here, copy this. All right. Let's try this again.  And that's why, that's why prefixes are quite useful. You can debug. All right. So let me try this again. This will actually, yeah, it'll launch a window automatically. So now when I try this again, I'm going to click on premium promos. What's going to happen? Let's see here. I think something else bad happened. Oh, all right. Boy. Right now is the, if it could go wrong, it will go wrong. All right. So let's just take a look here. It says, user is not assigned to the client application. So what I did wrong is over here under applications. When I go into my promos app right here, the thing that I skipped over was I did not assign the application to my current user. So I'm going to go in here, click on assign to groups. Select my everyone group, click on done. There we go. All right. All right. So now, all right. Now that we've done that, let's try this again. All right. So third time's a charm, right? So I'm going to click on premium promos. Oh, awesome. I got a token. All right. So here's what we're going to do. So just so you know, I got a token. So here's my access token. All right. Now, the access token has a problem. First of all, when I do the request, I don't have the proper scope, and I haven't added it to my outbound header. So let me just go back to premium promos and show you what happens. So when I click on get our premium promos, what happens is that I get an HP 401 response from the server. And the reason is, once again, is I don't, in the outbound request, I do not have the authorization header populated. In addition, I need to update this to request the promos reads go. So two things wrong right now. All right. All right. So what I'm going to do is I'm going to return to Adam, and I'm going to go in here, and I'm first going to make this change right here. So I'm going to say I also want promos read. I also want the promos read scope. All right. Down here under the auth header or get auth header function. So that's a bad idea. All right, there we go. Down here, I'm going to get the token using a little helper function up above. Let's just do that. And then we're going to add it to the outbound header. So remember, by the way, this is header is not header. I had a nickel for every time. This didn't work because someone did header authorization. So we're going to add it to the authorization header. It is a bearer token. Oops. Always make sure you do this space. That's another one. And then we're just going to take the raw access token and add it to the outbound header. Okay. All right. So now that I've done that, what this does essentially, let me just kind of show you, from the page that calls that basically does the request to get the promos, what it does is it says, all right, let's go add the access token to the authorization header. And then what we'll do is this gets called and then we add the access token to that authorization header right there. All right. All right. So now that I've done that, here's what I'm going to do is I'm going to go back here. And I'm going to, here's the thing, I need to delete the previous token. The reason I need to delete the previous token is it doesn't have the proper scope. All right. So taking a look here. Open ID, email and profile. In fact, why don't I just do this? So I'm getting back a 401. I'm still getting back a 401. All right. Because I don't have the promos read scope. Okay. So you could either click log out, which is what we do in the instructions. Let's do this. I'm just going to go in here and say delete this. So delete all my octa session storage. And now I'm going to request, basically request new tokens. All right. So let's take a look at the new token that I got. Email, open ID, promos read. All right. Now we have the necessary scope. So now when I go in here to promos read and click get our premium promos, my call succeeds. And if you want, you can check that out on the network request. Okay. You can go check out actually the resource server, the resource server basically got the valid request and returns the JSON response. All right. Okay. This means that we have an hour over an hour to work on the labs. So what we're going to do is because we have not that many people here who a lot of people signed up and then they didn't show up. We were, we sent this out to 125 people and looks like we have roughly, you know, I don't know. Looks like 25 people. No problem. So what we're going to do is we're going to jump into our labs. Let me just finish up my presentation. All right. So at this point. All right. What we're going to have you do is we're going to have you go to this URL. I'm Precky and I am here with Brian Demers. And we are here to do, or Brian's here, rather to do, to give you a demo and introduce yourself. All right. So I'm Brian Demers. I work with Aaron on Octa's evangelism team or advocacy team. Sorry. I said, my brain still, still trips on that every once in a while. But yeah. So I've been working, I don't know, on and off of the past year or so on this tool called the Octa CLI with the express goal of making developers getting started with Octa easier. So we talk about this a lot on our blog. You know, we write a lot of posts about how to use OAuth with X, right? Like I'm a Java guy, you know, by, by sort of history, I guess. So, you know, how to, how to integrate spring with, you know, Octa, right? It's all OAuth under the cover, it's all standards, which is great. And we do a lot of those types of posts, right? So your front ends or back ends, whatever you want. But they're all sort of the same when you get down to it, right?  And every IDP works like this, right? So if you, if you configure social OAuth with Google, it works the same way, you have to go to Google's dashboard and find the bits you need somewhere, you know, following some blog posts or documentation or whatever it is, and then put them in your application. And it's a little bit of a dance. So our goal with this tool was originally just to make that process easier. And it's sort of starting to grow and to be a little more than that, which is, which is awesome. But yeah, so, so I'm going to get started here. So the first thing, I should say the first thing, history, what history, here's some background I'm going to do, if you followed the first, the first lab session of the day, we built a little view application. And that, that whole process, I don't know, took people, once they got to the start with the lab, took any people from half an hour to an hour. And I'm going to try to do that in a couple of minutes. I'm going to drag the process out, because, you know, we're on this video.  So, so I'm going to try to drag it out and install everything. And then we're going to end up with a very similar app view, a few front end app that you would have had this morning, if you followed along. So the first thing I'm going to do is I'm going to share my screen. And then oh, come on, share screen. If I can remember how to do this. Here we go. All right. So I'm going to go to cli.octa.com. And we're actually improving this site. So so don't worry about that too much. And we're actually embedding some of these directions in our new upcoming blog post. And I know Matt Rabel, who was on the feed earlier, has definitely been doing a ton of work to update a lot of our blog posts with this information as well. But at the end of the day, if you're on a Mac, you use brew. If you're on Windows, you can use chocolatey. And if you're on Linux, you can use flat pack or both Linux and Mac also have a shell script option. But basically, you're going to get a binary, you're going to put it on your machine, and you're going to run it. Right. But that that's what these tools do. So if I've successfully uninstalled things to pretend I have a clean machine, this will work. So I'm going to grab, I'm going to grab that URL, or not the URL, the command, brew install, which is just installing this cask.  Hopefully. There we go. All right, so that's going to install the latest octa CLI. And it's going to link set up my path and do all that stuff for me. And then just to make sure everything's working. You can run the good old version command. Right. So everything, everything's good. It's installed. Pretty, pretty painless. If you already have an octa org, then you can you can run octa log in. Okay. But if you don't, and you need to go register, the CLI will do that for you automatically. So you can either run octa register, or you can just run octa start, and it will do the registration for you. If you've already logged in, running octa start will just use what, you know, your, your existing, your existing configuration. So, summarize this. Oh, go ahead. I have a question. Sure. So octa register, that means you can actually sign up for an octa developer account from the command line. Is that what it does? I should have led with that, right? Yeah. So I don't have to, yeah, I usually do, but it's a lot of form. Yeah. Yeah. So I usually leave with that, but it's so baked into my head now, just it's automatic thing, right? Because I've done this a hundred times, right? But yeah, so if you run octa register, I'm going to run octa start, but it kicks off the same process. And it will prompt you for an account and it will do all of the registration for you. So, you know, Brian, it's Merz, and I'm actually going to use my personal account here.  This, this will take a minute, but this will send me an email with basically a totp code.  And I'm going to go check my email outside of the screen here. We don't want to see your inbox. You do not want to see my inbox. I do not want to show you my inbox. All right. So I have a totp code. Now I need to find the streaming window again. All right. So I'm just going to paste this as a six digit code. I'm going to paste it in here one time use and hit enter. And that's verified my account. And then I'm actually going to go to this URL first to set the password. Oops, I can't copy from that screen. I'm seeing double on my end. So I apologize. All right. So this is my new octa org. So I've, I've literally set up a brand new account and I'm setting the password for the first time. And you know, make sure you use a strong password here. I bet you I typed this wrong. Use a password manager or something. But for the sake of this demo, keeping it simple, hopefully I can remember I did not type it right. So I knew I wasn't going to do it. So one of the downsides of passwords, right? Oh, seriously. Oh, it's a bad password. Oh, good. That's new to me. Okay. So let's do what was it? I'm not going to tell you. That's bad. Oh, it's terrible better. Yeah, I really should. I was just testing the system. Yep. It's nice, uh, pointing out that little feature we have there. Right. Right. It's really what I was down. Good. Okay. So, so I've logged in. I've just set my password.  Right. But I have an account. This is brand new. You can, this is a, uh, you know, free tier developer account. You can use this just like you were signing up through, you know, developer.octa.com. But jumping back to my terminal here, I'm going to continue. It's just waiting for me. So as I mentioned before, I'm going to create a view application, basically the same thing we would have done this morning in the lab. So I'll click number two. And this is going to download a sample app for me. And it's going to configure it. It's going to configure Octa. So it's going to set up an, um, an OADC application. It's going to create, get my secret. And it's going to configure my application for me all automatically. And I can get into that in a minute where those properties are and how that is. But the idea is, well, it's right here actually. Right. It's written to this property. But we'll get to that in a minute. So continuing with the demo, I'm going to change the directory, go into this new view folder. And then it's an NPM project.  Uh, so I can run NPM install. That'll take you an hour and a half. It's quick. Uh, it takes, I don't know, this one takes 20 seconds or so, depending on your internet connection. Hopefully I may have lied to you. NPM install is everybody's favorite step of this process. Yeah. Yeah. I mean, every tool does the same thing. I'm a Java guy. Maven downloads the internet. Um, you know, I, you know, Python does the same thing, right? All of these tools download the world. Okay. So great. So, uh, I've installed a package that means all the dependencies are on my machine. There's no, uh, vulnerabilities in this project, which is even better. We try to keep these up-to-date, uh, as possible. So then the last thing to do is run NPM start. And this, if I've done everything correctly, we'll spin up an application, or spin up the application. And I'm going to create a new incognito window. Hopefully, uh, you can see this one, right? Yep. Let's go back to, to this. This is still building and running. Uh, I'm using an incognito window just, just so, um, you can show, it'll show that, uh, it'll prompt me to log in. If I use the other window, I just logged into my octane dashboard. So it'll look like an SSO type, type of session. So cool. So this thing is all up and running. Let me grab, um, my URL. So it's just localhost 8080.  And if I click login, we're going to get redirected to octa, do the login dance and come back and all the OAuth stuff, you know, is handled behind the scenes. And Aaron can tell you all about that if you want. So if you have questions, put them, put them below. Let's see if I can remember that password that I just, I just had, I get it right. I did. Great. So, so now I'm logged in. So now I have a couple of other things I can see, right up here. I can see a profile and I can log out.  So this, you know, basically that's it. Right. So I've created, um, I've signed up for new octa account and, you know, that's free. Uh, I've downloaded a sample application, configured it for my new octa org. Um, and now I have a secure view application running in, I mean, I didn't time it, you know, a couple of minutes, right? That was pretty quick, I will say. Yeah.  There's this other little messages tab that's, that's combines with another example. If you have another resource server, that's sort of outside, uh, my demo for today, but. So wait a second. You didn't actually write any code. I did not write any code, not one line. That is correct. So, uh, and if I don't know enough or anything about security, I didn't have to write any at that security code, right? I didn't have to learn about, uh, you know, which OAuth flow is right for me or any of those. I just bootstrapped a new app. No, don't get me wrong. I feel it is important for to understand the security of your application, but I also don't want that to get in the way of me, you know, doing my business logic, right? Right. Well, and it's frustrating when it's kind of the first thing you have to do before you can even get started is figure out this, how to make your application secure. So this is nice that you kind of just get a good starting point. I see that it was using pixie. So it's using this more secure flow by default. And yeah, that's cool. Yeah, absolutely. So, um, we have a handful of examples in the CLI right now. So let me kill this and I will show you the list one more time. And so, so I've already registered for octa accounts. If I run octa start again, it's not going to register for a new account, right? I'm just going to drop it into, you know, pick a, pick a sample. But right now we have you, we have spring, angular, and a couple of reactive examples. We're adding more. And if there's something, you know, anybody wants to see, you know, let us know. And we'll, we'll jump on that actually. But, you know, I'm not a JavaScript guy. So, you know, I normally would pick like one of the Java variants, right? So pick whatever works for you. And the process works the same. You know, at the end of the render running start, it'll just say, you know, go back to your native tools, right? The spring one uses Maven. So it ends up being a Maven command. You know, the dot net one obviously uses the dot net tool chain. So you get a dot net command to run. And, you know, basically, the, the samples all look very similar. And you end up with a, with a functioning app. That's super cool. Looks like we have a, looks like we have a question in chat. Let me pull up the chat here. Josh says, trying to figure out how to install the CLI app in corporate environments where all the prefix are not allowed. So, yeah, that's a tough one. So you can go to, so let's see if I can, this is an incognito window here, but hit hub dot com. Whoops, I can't type can I octa and the repo is octa CLI. And you can hit up the releases and all the binaries, you can grab it from here.  So, you know, your mileage could may vary there. That, yeah, that might work. And Mike is also suggesting building from a source to, which I guess is definitely you can, you can build from source. There's nothing, there's nothing secret in here. So there, there are instructions back on the main page to at least there should be, if I've done my job correctly, right? Hopefully we stuck it in here. Ah, there we go. Yeah, yeah. So the project uses, uses Grawl VM, which is a Java runtime. Those details are probably not important unless you're interested in building the source. And you, but basically install it, run it, and you're done. Cool. That's fantastic. Yeah, this looks like a very, very good way to get started. It's certainly, so you had to go to the website to set the password, but that was the only thing you used the web, the octa website for, right? Was just doing your initial sign up. Yep. Yep. So, so all of the, the, the, you know, the idea here is that we, we want users to stay in their, their comfortable zone, right? So if you're, if you're, if you're not, if you're not comfortable with the terminal, don't use this tool. You, we have a, you know, user interface for you, we have instructions for those users, users too. That's totally cool. But if you're, if you're a command line savvy, and you know, you like the idea of automating the world, then definitely check out this tool.  Can you show us? I'm actually curious. I can, hopefully.  Oh yeah. All right. So we're back on here. Let me move some stuff around so I can show it. Whoops. I'm typing the wrong thing on the wrong window. Bear with me. All right. So I basically, oops, oops, oops. Once again, sorry.  So the configure, right, the configuration is all stored in in an octa directory in your home directory. And this is a lot of our SDKs work like this. It's very similar to like how the AWS tool works and those types of things. So I just moved my, my configure the way. So now if I run octa, octa login, it should prompt me for my octa URL, right, which would be, let me get this out of the way, which should be this URL. Did we show this earlier? There we go. This one right here. So I'm going to copy that and paste that here. Oh, it doesn't have to type HTTPS. That's a good question. Maybe you should solve it. You want to try that? Copy and paste. Yeah, try it without. All right, all right. Code it defensively. All right, we'll see if I'm, I don't think I'm that good. Yeah, so, so it, it does show you how to go find, you know, a decently, decently useful error message, though. So yeah, at least good. We did spend a lot of time on some of these error messages. All right, so let's try that again. With protocol this time. I thought probably should fix that, huh? All right. So now you did API token. So we, we have started updating our, our, all of our APIs to, to allow all tokens. So in the very near future, I hope that this tool will also use that, which you know, at least you can, you can downscope your token or however you want. And, and, but we have a bit of a chicken or egg problem that you need your auto or before you can go set up, you know, a token. So, so it's a, it's a, it's an interesting problem to work out. Right. Anyway, so this is sort of the traditional route of, you know, it's just an API key. So with octa, I can go over here to, what is it? Security, I think it's over here API. There we go. And then tokens. I'm going to create a new one for this demo. And I'm going to have to delete this, of course, right after this call. But yeah, I mean, you're going to delete the whole organ after the call. Yes. Yes. Very much so. Oh, I think he shows it to the screen. Terrible. Oh yeah. All right. But I am all set up now. So now we can run octa apps. And that's just going to list all my applications. So, so we took inspiration from, from the Heroku CLI. So if you're familiar with, with how that works, where we try to, you know, take, take some of the similar ideas, but this should run and list the app that I just created. So now I, I basically started with an existing org. I ran octa login. I typed in my, my URL, my API key, and now I can run other commands. And there's a hidden feature in here too. It's called octa logs. I can see all of, you know, my log activity or whatever. So there's, there's, there's some cool things we're, we're trying to add in here as we go. Yeah, that's awesome. That is super cool. Yeah. So do we have any other questions? Can I answer anything else or What do you think? It looks like Matt wants a shirt that says I heart the octa CLI. I too want a shirt that says I heart the CLI. Yeah. So Matt, you should, you're the t-shirt wizard now, I think. So you should get on that. Oh, Matt wants to know about octa logs. Why did that? Why was that a hidden feature? So I don't know, to be honest. So like, I do know. So it ended up being from a hackathon. So one of one of my colleagues created a hackathon and used, used to go, I think, but I remember right to, to sort of prototype some of these ideas. And he had this logs command. And I wanted to see if it will work. So, so I, I, I quickly added this octa logs feature, but I hit it because it's a little tricky because you're the logs at octa are a little delayed. I think there's up to like two minutes delay. So if you're following your logs and you log in, it's not super obvious. It makes sense from oxygen replication and whatnot, right? But you know, if you're watching this, go ahead and use it. But you know, there's some limitations that I think we just need to document around before. Yeah, it's true. I would expect a CLI log tool to be tailing it in real time. Right, right. So, so that delay is sort of, I got you if you're not ready for it. Yeah, yeah. I mean, it might, it might be seconds, right? But, but it's up to two minutes, I think. Yeah. No, that's fair. Matt, Matt has another question. How do I add new redirect URIs to an app? That is a great question. So if you have an existing app, you cannot yet do that through the CLI, you'd have to go through the octa dashboards to it. I know, I know Matt has been, he would love to see something like, you know, I think, I think, I think ultimately what we want is probably like octa. Oh, yeah, there you go. Thank you. Octa apps config, like your eye or so or redirect URI or something, something like that, I think is our goal. And then, you know, you could add your new one here or set them, you know, it's an array. So it's a little tricky. Do you, do you require somebody to update the whole list?  Yeah. Yeah. So, so there's some tricky things we have to work out, nothing, nothing monumental, right? We just need to sit down and think about it for a few minutes. But yeah, fair enough. All right. Well, cool. I think we're about at the end of the time. And that was an awesome demo. That was very straightforward, very pretty easy way to get started. Definitely exciting. And it's going to clean up our blog posts a ton. I know. Yes, yeah, Matt, I know Matt's been working really hard updating a ton of blog posts. So we, you know, for for background, we just updated the admin console and octa. So things are a little different. So, so some of the UI didn't quite match up to a lot of the screenshots we've taken before. So Matt has been going through and updating a ton. So he's been, he's been, you know, doing all the heavy lifting. Yep. Everybody should send Matt nice comments. Absolutely. Absolutely. Yeah. All right. Well, that's, that's it for this. Thank you, Brian. Thanks for joining the stream today. Thanks for having me. Yeah, absolutely.  So thanks everybody for joining and we are back. Good to see everybody back here again. Thank you all for joining and back here with Micah again to wrap up the day with a couple of things. We'll be doing random Q&A again. So as always, feel free to drop questions in the chat if you are watching live and Micah will also be showing the Heroku demo. So nice. Yeah. So we kick it off. Why not? Let's do it. All right. So let's see where I go to share my screen. Not that one. This is what happens when I give Micah director power in the stream. There we go. Okay. Is it correct? Yeah, looks good. My Heroku screen. Okay, cool. So just in case you're not familiar with Heroku, it's an application hosting platform. It's very easy to use. It's very robust. And one of the cool things that it has is this notion of add-ons. And if you are familiar with Heroku, you've almost certainly used these. You can go and add say a MySQL add-on. Yeah. I've added like databases and like Redis. Yeah. Postgres, Redis. Oh, here we go. Find more add-ons. That's what I was looking for. Right. So it has all of these and really handy stuff for just about any type of application you'd be deploying. I forgot what I just called this here. Like a general demo. So I can add a free tier of MySQL super easy to this app. And from here, I can switch over to a paid tier if I want and may all have different levels of access. And just by virtue of adding this, in this case MySQL, it also sets a bunch of configuration like this JAWS DV URL is now connected to MySQL instance. So that's generally what add-ons are in Heroku. And we've created an octa add-on that makes it super easy to add octa to a Heroku app. And if you tuned into the previous demo from Brian, this is very similar to what's going on with the octa CLI. And it even shares some elements of the back end. So what I thought I would do here is show you in the context of jhipster, which Matt demoed earlier, jhipster has support built in for deploying to Heroku and for the octa Heroku add-on. So it makes for kind of a full circle demo here. And I previously installed jhipster. And so I'm just going to run this command to create a jhipster app. And it's going to ask me a bunch of questions. I'm going to create a monolith application.  I don't want web flux. So I'll leave the default package name. Now here's where things get interesting. And we're all in this kind of ties together. So jhipster has some sensible defaults. And one of the defaults it's assuming is that you're going to build an app that needs auth. And there's a bunch of different options here. But we can choose awath and oidc. And it works with key cloak and octa out of the box. Key cloak is a very robust, well written kind of on-prem awath server. Octa is a cloud service. And it works with either of those. I'm just going to select some other defaults here. No database, no cache. We'll leave it as maven because everybody knows maven is better than gradle. Thank you, Matt. And I don't need anything from the jhipster registry. We can choose a front end.   I'm just going to choose react. I don't know react very well, but we'll see at the end of this that I have a fully running ready to go application that's integrated, that's deployed to Heroku and integrated with octa. I'm not going to worry about generating an admin UI. I have some choices for themes here. I don't want internationalization support. I don't need anything extra. And so now it's going to generate this application. Now I'm actually going to let this one run because it doesn't take too long. The next step takes a little bit longer. And so I pre-created a jhipster app with Heroku integrated. So we'll do a little bit of the old style cooking shows in just a moment where I'll take the completed recipe out of the oven while the real one is cooking. This should just take a moment. And this is setting up everything that we need for the front end app, which as Brian talked about earlier involves downloading the entire Internet with many NPM type projects. But this doesn't take that long, about a minute, unless I'm lying. I think we're just about done. Give me back my command line. There we go. All right. So now we have a basic jhipster app that's ready to integrate with an OAuth service of my choice. Now I'm going to set it up so that it's actually going to deploy to octa and use Heroku. And to do that, I just type in jhipster Heroku. Oops. That was not what I meant to do. Here we go. jhipster Heroku. Now it's going to ask me a couple more questions. I'll leave that as it is. I'll deploy to the US region. We'll use Git, Java 11. And here's where I can say yes, provision the octa add-on. So this is where it's going to not only deploy this application to Heroku, but it's going to provision octa along the way. And similar to what Brian was showing, we're going to see that there's no need to interact with the octa admin. This is all command line stuff. Is there a question? This is doing a bunch of things at once. This is up until this point, you've now got a running application that you could run on your machine, right? Right. But next step is to deploy it. And you're going to both push it to Heroku and make an octa account at the same time. That's right. So there's a lot going on. And maybe it's a little bit understandable why this particular part takes a little longer. But it's doing all that right now. It's preparing the app to deploy to Heroku. It's allocating an octa org. And it's actually going to deploy it to Heroku. So I'm going to let that run. But here's the part where we can do the old school cooking show type of scenario. And here's it fully baked out of the oven. So what you're left with is a user ID and an initial password, which is just a UU ID, which you can use to log in. And you can also, if you're familiar with the Heroku CLI, you can see the config that's been set for this octa instance. And it includes an octa org URL. It includes an API token. It's set up a couple of applications and configured environment variables for those applications. So we have a SPA, an OpenID Connect SPA app. We have a web app as well and an issue where all of this is set up so that I can now go to this app. And I called it JIP Hero Demo. And I'll bring up an incognito window here and jump over to that app. And it's probably been put to sleep through inactivity. I forgot to preload it before this. So it'll take a moment to wake up. We can actually watch that happen. There we go. So here's kind of your vanilla, you know, cookie cutter React J-Hipster app. But I have some navigation here, and I can go and sign in. And this now redirects me to this octa org that's been configured, created and configured for use with this, with this application. Now I could use the... Oh, I might have scrolled it off the screen. Here we go. I could use this other user that was set up for me. This is an ordinary user in octa. But part of the provisioning process also creates a super admin user. So I'm just going to log in with that super admin user. And you can see that all of this is changeable after the fact, but the initial user ID and password involve these random new ID values. So I'm going to paste those two bits of information in. Now I'm going to get hopefully redirected back to the application in an authenticated state. So all of that was done without having to visit the octa admin console at all. And this is running in Heroku, and it's now ready for me to customize and really build out this app, but I don't have to worry about the auth piece is kind of just taken care of here. Right. That was pretty seamless, actually. So you have an app now not only built, but also deployed to Heroku. And it is running on Heroku and already configured with octa for login. That is kind of amazing. Yeah. Oh, and one other thing that I think is worth showing here, and this is part of the Heroku experience. So I called that J-Hip Hero demo. Similar to what you would find with MySQL or Redis or any of these other add-ons, part of the requirement of building an add-on is that you provide SSO from Heroku to whatever the add-on is. So coming over here, you can click on octa and this will jump you right over to your octa org without any additional authentication required. How does that work? Oh, it's some serious voodoo involved.  They don't use a standard, which is unfortunate in my mind. I love Heroku, but I think that's a mistake. But we implemented all of that so that it would work properly. You have to implement that on the add-on, I assume, because octa doesn't support Heroku's proprietary. Correct. Yeah. So over here in the octa org, I can see that these apps that have been created, here's a little peek. Oh, there's the one for their SSO, okay. Yeah. So there is maybe a hair of fragility in there for people watching. It says, do not alter here. If you were to, say, delete this app that was created in octa, that would break SSO. So that's a little more fragile than we would prefer, but- You could still log in to your org with a pan of screwed red. That's exactly right. You never lose access to the org. The only thing you'd be breaking is this Heroku to octa SSO. So I wouldn't call it a security risk per se. It's more of a kind of user experience risk if you were to break that. But you're always a command away from the initial config, which includes a super admin login. So you can always log in directly to the octa org. You may not even want to use that SSO mechanism. So you have another way to get to that octa org if you need to. Yeah, makes sense. It's very cool. Thanks. Yeah. And we are literally, we're in beta right now with the Heroku add-on and it's literally going to GA on Monday. Oh, fantastic. Okay. So can we use it in beta right now or not till Monday? It's only a few days away. Yeah, you can use it right now. Once it gets the way that Heroku works, once it's in beta, it's publicly available. It's publicly searchable. So anybody can use it right now. That is very cool. Yeah. So happy to answer any questions about that or anything else anybody wants to talk about. Yeah, awesome. Thanks for the demo. Let's see. We do have a question. Will this video session be available for viewing after on this channel? And the answer is yes. So we will leave this stream up for viewing later in case anybody wants to. And with any luck, I'll hopefully segment out the individual demos as their own videos as well so that you don't have to scroll through a six-hour long live stream. Nice. So yeah, for the rest of the time, we will feel free to drop in more questions about OAuth, Heroku, J-Hipster or whatever into the chat. We'll answer questions. Otherwise, we're just going to keep talking about stuff. So you're going to get whatever you get unless you come with your own questions. Yeah, a lot of cool stuff going on. I think it's a lot easier to get going as a developer now with this stuff thanks to all these little tools. Yeah, I got to say, I hope other people have the same experience, but this has been kind of a fun day for me. We covered a lot of ground, did a lot of hands-on stuff. That's for any conference I attend. That's the stuff that seek out the hands-on stuff, the stuff I can kind of go along with on my own computer while watching what somebody else is doing. So I hope everybody else enjoy it too. Yeah, I hope so. We had a lot of good demos, a lot of good... The labs were a lot of fun to do that. And you got a sneak peek of the hands-on exercises without having to actually be part of the enrolled course. So that was nice to be able to do that and share that with everybody as well. Oh, this is a great question from Matt. What was the hardest part of developing the Heroku add-on? The hardest part was the SSO piece for sure. It required a little bit of API gymnastics to bridge that gap between Heroku and Anastas. Yeah, as somebody who lives and breathes in the Oauth and OpenU Connect space, I am fascinated by that part of it. But it sounds like the Heroku is actually doing the SSO to your little app that's running and that app is doing OIDC to Okta, to that app you created in Okta. Is that correct? Ultimately, yes. There's a little bit of stuff that happens in between what you just described. But yes, the last leg of the SSO interaction is to hit an OIDC endpoint having established a session with Okta. Yeah, that is some gymnastics. I feel like the double layer, two-layer SSO flows are always hard to keep track of in your head. Yeah, indeed. Even when they're both OIDC and not to mention some proprietary thing. Yeah, that's right. Do you have any thoughts on Heroku's proprietary mechanism? Is it kind of like OpenU Connect or is it like SAML or is it just something totally different? I mean, it's kind of old school. As a security professional, I'm impressed with it because it's robust, it's well thought out. The other edge of that sword is kind of just leaving me wondering why. And I've had this conversation with Heroku and again, lots of love for Heroku, but this is one decision that I find is a little bit of a headscratcher. And I guess, I mean, if I wanted to play Devil's Advocate and try to get into Heroku's head, they're dealing with businesses from Redis to MySQL to Postgres to Okta. There's hundreds of these add-ons and very disparate types of businesses. And also to their credit, their mechanism for SSO has been around for a very long time. What would make it easier on us and make it less fragile would be if Okta's back-end supported it, its core back-end. And that's just for a little bit of history. That's what we ended up doing at Stormpath way back when our engineering team actually added a little back-end support for Heroku's SSO mechanism so that we didn't have to go through API gymnastics. But my own personal opinion, without any sort of background or knowledge of what they went through, is that it would be just as easy to build and support for a standard as it would be to roll your own. So if, for instance, they supported OIDC since we have the ability to support OIDC, generally it would have been a pretty simple matter to provide SSO from Heroku to Okta. Right. Do you know when they made their initial support for SSO? Do you know when they developed it? That's a really good question. I mean it's seven to ten years ago minimum. It's been around a while. Okay. So OIDC was still pretty new at that point then I would say. Because OAuth was finalized in 2012 and OIDC builds on OAuth, which means it can't have been finalized before that. Yeah. Again, without really knowing what's going on behind the scenes at Heroku, I would say, at least from the outside, they have thousands of these add-ons and their system seems to be working. They keep getting other companies like Okta to add more add-ons. So they may just kind of think, well, it's not broke, so why fix it? It's not broke and it's been around for so long that they do have a real excuse for why it's not a standard space approach. And if they don't really gain much by switching to a standard, then there's not a lot of motivation for them. The main benefit, I would guess, would be that it would let companies like Okta integrate natively as opposed to having to spend more engineering time on the integration. So it depends on who has the power dynamics there, I guess. Right. Yeah. It's interesting. Yeah, it'd be interesting to see prior to Salesforce acquiring Heroku if it might have been a different dynamic. But if it's Okta saying, hey, go support OIDC and Salesforce saying we have this SSO mechanism, it's kind of an even match at that point. Yeah. Heroku, a Salesforce company, is kind of like, well, if you want to have an add-on on our platform, here's what you have to do. Right. Yeah, that's a tough one. We have another question from the chat. So how can we delegate responsibility, for example, only team A can manage their authorization servers, set policies and rules, but other teams with their own AS can't? That's a good question. There's a whole section now for applications where you can use OAuth for apps and there's a pretty fine grain of scope control. I don't know if that's one of them off the top of my head. I could take a look. I don't know if, you know, control of authorization servers or a particular authorization server is one of those scopes. I do believe that there's an Okta admin type that is, I'm going to look at this right now real quick, but I believe there's an Okta admin type that is like an OIDC manager or an authorization server manager, and you can limit that type of administrator to one particular authorization server. So they could add new scopes or new claims, they could assign which apps can use that authorization server, but they wouldn't be able to do that in any other authorization server for the same Okta or. I'm going to double check on that right now and I'm going to use the SSO from Heroku to Okta to do it, just to check it out. Why don't I share my screen again real quick and we'll go on this little journey together. So let's see, if I go to security and administrators, this is one way that I'm thinking of, and here's admin types. API access management is an admin type and I'm not entirely sure what that gives you access to. So let's go to types, this is moving to developer section, go to developer.okta.com, look for administrator roles, how about that?  Is it describing the API for it? What about just concepts for administrator roles? Let's take this back to Google. That's the API reference, that's help. Let's see, there's somewhere in our docs and I should be able to find it more easily that we have a table of these admin permissions. Yeah, that makes sense. All right, well, can you just try it? It's a little bit of a fail, but I'll see if I can find it and if I do, we'll go from there. Yeah, but anyway, the overall goal of what you're looking for is creating a user with a specific set of permissions? Yeah, I think the idea would be you have a user and you can assign that user an admin role like API access admin and that would give them control over an authorization server where they could configure that authorization server on whatever way made sense, but they wouldn't have access to other authorization servers. So you could kind of partition out your administration that way if you have multiple authorization servers. So that sounds like, okay, yeah, it makes sense. Using authorization servers to segment who can manage them. Right, which hopefully I didn't miss the nature of the question altogether. It seemed like that's what they were asking. Yeah, well, speaking of multiple authorization servers, that was actually something that came up during Chris's lab earlier. He was talking about using multiple API or multiple authorization servers to segment out different aspects of your own API and your own access control, which I think is always a question people ask is why would you want to add more than one authorization server or when might you need more than one? And I get some good examples in there, I thought and yeah, it's interesting. So the way it works in Okta is the one authorization server gets one audience claim. So this is the idea is that the authorization server issuing access tokens will put a particular audience string into the access token and the audience is meant to represent the API that it is protecting. So basically you would have one authorization server per API that you are building.  But you could also decide that your API that you're building is actually a bunch of different logical APIs and you might have an API for processing actual orders like taking orders and doing the checkout flow and a separate API for managing the product catalog where those are pretty different APIs even if they share the same backend database. And then it makes sense to have multiple like one authorization server for each one because those access tokens aren't going to be used by the same app talking to both of them right. You're going to have your application for your staff to manage the inventory and a separate application that's your public facing app that's your shopping you know your catalog and shopping cart. So I think that's a nice example of when it makes sense to use multiple authorization servers and how you might use those different audience values. Yeah. Did you find it. I think I did find a reasonable reference here. Let's. I got it.  No I just wish I had you. Nice. So you can see my screen now yeah. Yeah. Sweet. So this is in our in our help center and it's kind of this massive table of all the different admin roles but it has this API access management admin role that you can assign to a user. And it kind of covers the things that I was talking about. So like you can this may be like super small for people but you can you can add delete edit authorization server scope claims and policies. You can you can view users that are that are assigned to the but is that across is that across all authorization servers or can you assign it to a particular authorization server. I believe that you can assign it to a particular authorization server. Let's just see if I add an admin role to this J. Hipster user. Right now this is an ordinary user that was set up as part of that J. Hipster. So I'm going to say API access management administrator. And then I should be able to actually now I didn't have to like assign this user to any particular authorization server. So maybe it is not entirely clear to me but it looks like it might be general overview of any authorization server. So maybe that's a good feature request. Right. Yeah. And now I think I did change the password on this array. So let's go see what I can do. Yeah. So it looks like I can add a new authorization server and then it looks like I can mess around. But you can still change the one. Yeah. Yeah. Yeah. That's yeah. Well let's get a feature request being able to assign assign users to specific authorization servers. Yeah. Indeed. So yeah file that as a as a where is it the ideas website I guess. Where is that. Ideas. Octa.com just drops into a log in. I think that is the right site though. Anyway. Yeah. Good question. Oh and Josh says I saw there was something on a future robot for more detailed roles. So maybe it would be part of that enhancement. I don't know if that is the case but that that is hopeful. The whole OAuth for Octa stuff is relatively new still as well. So hopefully that continues to improve in the future. Yeah. Yeah. Well cool. What else. Do you have any other ideas about multiple authorization authorization servers. Yeah. We were talking a couple of us talking a little about this earlier and you know I certainly created a bunch of apps micro services architecture or an app that for one reason or another has multiple resource servers. And when it was all kind of in the same you know problem domain of the app I just reuse the same authorization server even if it was a different resource server. But I can certainly imagine a scenario where you have very disparate services and maybe you want to you know be able to compile them or you know have different configurations for different applications where some applications can access some and some cannot or they're put together in different ways. And I could imagine having different authorization servers in that scenario where you have like a real kind of apples to oranges sort of resource servers that do very different things. You know if it's a cluster of resource services for high availability or if it's different resource services that are kind of you know in service of the same application then it seems like you could just make use of the same resource server which is actually kind of handy because then you know you have an access token that yeah you have an access token with the right audience and you know you can hit different API endpoints on different resource servers with the same access token. I think another thing to keep in mind there is that you get to define policies on within an authorization server on token lifetimes. So how long you want tokens last how they should be issued depending on scopes and roles of users and all those kinds of a lot of rules you can sort of stack up to create your policies and that lives within one authorization server. So if you have rules that you may want that you may want relatively complicated rules that exist within a certain area because they're talking to certain backends it may become too complex to try to manage those rules along with a set of rules for a totally different set of use cases. So drawing a line there makes sense where you can separate those two out so that you aren't having to make sure your rules don't conflict with each other or or interfere with each other in strange unexpected ways. Yeah and that's a good you know as developers we might call that a code smell but like a policy smell if you you know if you have tens of rules in your in your policy you know it's kind of an indicator that maybe you need to break things up a little because we get a lot of help requests where I think the most common one is where somebody's not getting issued a token and they expect it to be and it turns out that you know they're they're hitting a deny rule you know before the the accept rule would have gotten hit in in their in their policy you know their their policy stack. So if you're getting into really complex policies and rules that can be an indicator that you might want to break things up a little. Yeah that makes a lot of sense well cool um any other thoughts otherwise we can we can close things out it's a little bit before our scheduled end time but I feel like we've done a pretty good overview of of a bunch of different topics today it's been a wild ride and thanks Micah for joining sure co-host of today on your very last day of work. Yeah it's been a treat but one thing I might add just in closing is for the projects that we kind of featured today um they they're all open source j hipsters open source the uh the the octa cli has an open source component to it even though there's a private back end um and uh you know same thing with the Heroku add-on and so if you know feature requests github issues um those are all you know at the the general community's disposal if there's uh if it's behaving in a way that doesn't make sense or you want to see a feature added um you know we're really these are all kind of new technologies that we want to see the developer community really embrace so we're really listening yep it looks like we have the link for the octa cli is this one and we also have a separate org for some of the developer tools as well which is um is that octa developer got on github yeah yeah oops geez clicked too many things um the yeah so this link on on github is this bunch of other demos there and then of course the uh always happen here from you as you know from filing issues on those repos and things like that uh we also have blog posts of a bunch of the content uh demos of these things that we've been talking about so leaving comments on those blog posts is a good way to get in touch as well if you have problems or questions or feature requests you know we do read the comments on the blog posts so it's not a good place to try to to get in touch with us yeah and uh josh thank you for all the questions as well that uh saw you pop up here a bunch of times so awesome thanks for joining a lot of a lot of it's a great crowd today a lot of good questions for uh developer focused content today it's been great yeah and one other link i'll just put in uh to youtube chat here this for the octa heroku add on the way to uh list issue you know post issues or ask for features is through uh heroku's elements sites since the back end of that is private source that's the best way to get our attention for the octa heroku add on cool okay is that like through the heroku's web interface yeah there's a there's a link there there's a support link there that uh you know finds its way directly to our support team and and depending on what it you know the nature of the support would find its way to us um and that would be a good place to put in issues or feature requests or anything else great beautiful yeah and what was linked to that uh that or is it just in there in the add-on once you're in the add-on well you can get to it directly from the add-on but also in the page that uh that you just had up at toward the bottom there's a support link that has a lot of the like oh that that page that you were on has a lot of overview information and you know it shows the beta tag still that'll go away on monday but toward the bottom there's a uh it also has a bunch of documentation there uh which if we've done our job right you don't really need but if you are curious you can uh you can go look at that documentation um but uh the uh the it's got some direct email support that comes that comes right back to us got it yeah great well um yeah thanks for that all right uh and i guess i guess with that we will uh wrap things up so thanks to everybody for joining today it's been a marathon of a live show so this will stick around on youtube so you feel free to watch back the replay if you want uh anytime and uh subscribe on youtube give this video a thumbs up subscribe so you can make sure you don't miss our other content because we're posting we post up here all the time and we're gonna post a bunch of the talks from from octane our developer talks here as well so you'll be able to watch those if you miss them if you miss them live during during octane 21 those will be on the channel here shortly so yeah excellent uh with that thanks everybody for joining and see you in the next video