Hybrid identity engineering / Portfolio project

Hybrid Identity &
Access Management.
AWS Active Directory + Okta.

From an empty AWS network to a working hybrid identity system: I built a Windows domain controller, integrated it with Okta, resolved connectivity and import failures, and tested authentication, federation and access removal through restoration.

Windows Server 2022Okta Identity EngineSAML 2.0Group-based RBACHands-on lab
01 / Architecture

AD owns the identity.
Okta connects it to the application.

The lab uses self-managed Active Directory, not AWS Managed Microsoft AD. A single EC2 server hosts AD DS, DNS and the Okta AD Agent for the domain ad.phylaxcyber.com.

AWS / Active DirectoryPHYLAX-DC01
AD DS + DNS + AD Agent
Users, attributes and security groups
OktaAD imports
Delegated authentication
Email verification + app policy
RSA SAML demoPHYLAX-SAML-SSO-LAB
Group-derived entitlement
SAML assertion accepted
ACTUAL LAB TOPOLOGY
VPC 10.50.0.0/16 contains public subnet 10.50.1.0/24 and one Windows Server 2022 EC2 host running AD DS, DNS and Okta AD Agent. Outbound HTTPS connects to Okta SaaS; browser SAML connects to RSA test SP; administration uses SSM with no public RDP.
One server, one public subnet. Separate private hosts were not deployed. Download vector diagram · Download PNG
No public inbound RDP.Systems Manager and Fleet Manager provided administrative access. The lab used a public subnet for outbound connectivity, an encrypted EBS volume and an EC2 role with AmazonSSMManagedInstanceCore.

The AD Agent connects outbound to Okta over HTTPS. AD validates the user's password; Okta applies authentication policy and issues the SAML assertion. Group membership determines who receives the application assignment.

02 / AWS foundation

Start with the network, then establish secure administrative access.

I chose self-managed AD on EC2 to build and troubleshoot the directory myself. The lab ran in us-east-1 on a Windows Server 2022 t3.large instance named PHYLAX-DC01.

ResourceLab configuration
VPC / subnetPHYLAX-IAM-VPC — 10.50.0.0/16. PHYLAX-PUBLIC-SUBNET — 10.50.1.0/24.
Internet routePHYLAX-IGW attached to the VPC; PHYLAX-PUBLIC-RT associated with the subnet and a 0.0.0.0/0 route to the internet gateway.
Security groupIAM-SG with no inbound rules. The wizard’s public RDP rule was removed. Outbound traffic was allowed; the network ACL also allowed traffic in both directions.
Instance accessPHYLAX-EC2-SSM-Role with AmazonSSMManagedInstanceCore. CloudWatchAgentServerPolicy was also selected during setup, but configured log collection was not demonstrated.
Storage / metadataEncrypted 50 GiB gp3 root volume, 3,000 IOPS, AWS-managed EBS key and deletion on instance termination. IMDSv2 required.
Private addressThe deployed server used 10.50.1.103. The earlier proposed 10.50.1.10 address was not the final configuration.

1. Resolve the missing outbound path

The instance launched without a public address and initially failed to register with Systems Manager. A connection attempt to the regional SSM endpoint on TCP 443 timed out. I checked the subnet route-table association, internet gateway route, security-group egress, network ACL and address association. An Elastic IP supplied internet connectivity without a NAT gateway for this lab. SSM then showed the instance online and a session connected.

Public subnet did not mean public RDP.No inbound RDP rule was added. The Elastic IP supported outbound connectivity; its value is excluded from this public case study. The permissive egress and ACL were lab choices, not a production baseline.

2. Recover Windows administrator access

No EC2 key pair had been selected, so the usual initial Windows password decryption was unavailable. In the SSM PowerShell session, whoami identified ssm-user; group checks showed enabled local administrator membership. I set an Administrator password through an interactive prompt and connected using Fleet Manager Remote Desktop.

Administrative checks and password prompt
whoami
whoami /groups
net user Administrator *

The prompt keeps the new password out of the command text. Use a unique password and do not put it in screenshots, scripts or the repository.

03 / Windows directory

Create the forest and prove that AD DNS works.

3. Install AD DS and rename the server

I installed the AD Domain Services role and management tools, then renamed the generated EC2 hostname to PHYLAX-DC01 and restarted. Before promotion, I replaced the initially proposed test namespace with ad.phylaxcyber.com, using PHYLAX as the NetBIOS name.

Role installation and forest creation commands
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
Rename-Computer -NewName "PHYLAX-DC01" -Restart
# After restarting, run in an elevated PowerShell session:
$dsrm = Read-Host "Enter a unique DSRM password" -AsSecureString
Install-ADDSForest -DomainName "ad.phylaxcyber.com" `
  -DomainNetbiosName "PHYLAX" -InstallDNS `
  -SafeModeAdministratorPassword $dsrm

These commands express the intended secure procedure. Do not repeat Rename-Computer on an already promoted domain controller. Promotion restarts the server.

4. Troubleshoot the DSRM password input

Forest promotion repeatedly reported password complexity failures. Policy inspection showed complexity enabled. A diagnostic revealed that one hidden-input attempt had captured only one character, explaining why apparently complex entries failed. Promotion eventually succeeded after correcting input handling.

Security lesson from the troubleshooting.A plaintext workaround was used in the original session. It is deliberately excluded here. Rotate any exposed lab credentials and use a reliable secure input path; weakening password policy is not the recommended fix.

5. Validate the domain and DNS

Get-ADDomain returned the new forest and PHYLAX NetBIOS name. Local DNS resolved ad.phylaxcyber.com to 10.50.1.103, and dcdiag passed its connectivity and DNS tests. The server’s DNS client used 127.0.0.1. A DHCP-related warning remained; the lab retained the EC2-assigned private address.

Directory and DNS validation
Get-ADDomain | Select-Object DNSRoot, NetBIOSName, Forest
Resolve-DnsName ad.phylaxcyber.com -Server 127.0.0.1
dcdiag /test:DNS
Get-DnsClientServerAddress -AddressFamily IPv4

AD DNS stayed inside the directory environment. Public Route 53 records were not needed to expose this domain controller.

6. Create dedicated OUs, a test user and the access group

I created PHYLAX-Users and PHYLAX-Groups below the domain root. John Doe was a synthetic user with sAMAccountName jdoe and UPN jdoe@ad.phylaxcyber.com. After setting his password, I explicitly enabled the account. Okta-Users was a Global Security group in the group OU; adding John established the directory-side entitlement.

OU and group commands
$base = "DC=ad,DC=phylaxcyber,DC=com"
New-ADOrganizationalUnit -Name "PHYLAX-Users" -Path $base
New-ADOrganizationalUnit -Name "PHYLAX-Groups" -Path $base
# Create jdoe in PHYLAX-Users with a unique securely entered password.
Enable-ADAccount -Identity jdoe
Get-ADUser jdoe -Properties Enabled,UserPrincipalName
New-ADGroup -Name "Okta-Users" -GroupScope Global `
  -GroupCategory Security -Path "OU=PHYLAX-Groups,$base"
Add-ADGroupMember -Identity "Okta-Users" -Members jdoe
Get-ADGroupMember -Identity "Okta-Users"

Creation commands are for a fresh lab; they are not an idempotent deployment script. The PDF contains the fuller user-creation procedure.

04 / Okta integration

Bring AD identities into Okta, then authenticate against AD.

7. Install and register the AD Agent

From Okta Directory Integrations, I added Active Directory and downloaded the Windows agent installer. The lab used agent version 3.23.0 and the OktaService service account. Registration used the Okta administrator activation flow, with direct outbound internet access and no proxy. Activation codes and organization identifiers are excluded.

I scoped the import to the dedicated lab OUs rather than selecting the domain root. The user OU was PHYLAX-Users; the lab group OU was PHYLAX-Groups. UPN was selected as the Okta username format.

8. Import, match and activate the identity

A full import discovered John Doe, but discovery alone did not create an active account. I selected the staged user, confirmed the assignment and enabled auto-activation. Okta then showed John as Active and AD-sourced. Okta-Users synchronized as an AD-managed group, so membership changes belonged in AD.

The integration imported directory identifiers and user attributes. Optional profile fields were discussed, but no ABAC or governance policy was tested. A provisioning mapping warning did not establish reverse provisioning or password writeback.

9. Test delegated authentication and fix email delivery

I enabled delegated authentication and its test succeeded. A fresh browser login then reached email verification. The UPN was a lab sign-in name, not a working mailbox, so I updated John’s AD mail attribute to a reachable private email address and ran an incremental import. The imported email received the code and sign-in completed.

Email attribute repair
# Replace the example with the test account's reachable mailbox.
Set-ADUser -Identity jdoe -EmailAddress "test-mailbox@example.com"
Get-ADUser jdoe -Properties mail,UserPrincipalName |
  Select-Object UserPrincipalName,mail
# Run an incremental import in Okta, then test a fresh sign-in.
Three identity values had different purposes.The AD UPN remained the Okta login identity. The private mail attribute delivered the verification code. The SAML test returned the lab UPN as NameID. Email verification worked, but is not phishing-resistant authentication.

10. Replace the unavailable SAML test service

The first custom SAML app attempt targeted SAMLtest.id, which was unavailable during the lab. I switched to the RSA SAML Test Service Provider from the Okta catalog and named the application PHYLAX-SAML-SSO-LAB. Assigning Okta-Users gave John the app tile. Launching it produced the RSA “Hello John Doe” result and an accepted SAML assertion.

Service-provider metadata and endpoints depend on the chosen service; the record does not support inventing exact ACS or entity-ID values. The captured result, rather than a proposed configuration, is the evidence of successful federation.

05 / Identity lifecycle tests

Build it. Change access. Verify the result.

With the baseline login working, I changed AD state and ran imports to check the effect in Okta and the application. These tests distinguish entitlement removal from disabling an identity.

TEST 01 / BASELINE

Confirm group-derived access

John was active, Okta-Users contained him, the app assignment came from the group, and RSA accepted his SAML login.

TEST 02 / REMOVE ACCESS

Remove AD group membership

Remove-ADGroupMember removed jdoe. After incremental import, Okta-Users had zero members and the fresh dashboard had no app tile. John remained Active.

TEST 03 / DISABLE IDENTITY

Disable the AD account

Disable-ADAccount changed AD Enabled to False. Importing this change caused Okta to display Deactivated.

TEST 04 / REACTIVATE

Resolve the inactive match

Enable-ADAccount restored AD Enabled to True, but the matching Okta identity stayed inactive. Import confirmation initially failed with auto-activation unchecked.

TEST 05 / CONFIRM IMPORT

Activate the existing identity

I confirmed the matching import with auto-activation enabled. John returned to Active. This step required administrator confirmation in this run.

TEST 06 / RESTORE ACCESS

Restore membership and federate

I added jdoe back to Okta-Users and imported again. The group contained one member, the app showed a group assignment, the tile returned, and SAML login succeeded.

Lifecycle commands used in AD
Remove-ADGroupMember -Identity "Okta-Users" -Members jdoe -Confirm:$false
Get-ADGroupMember -Identity "Okta-Users"
# Import and verify entitlement removal in Okta.
Disable-ADAccount -Identity jdoe
Get-ADUser jdoe -Properties Enabled
# Import and verify Okta deactivation.
Enable-ADAccount -Identity jdoe
# Import and confirm the matching user with auto-activation enabled.
Add-ADGroupMember -Identity "Okta-Users" -Members jdoe
Get-ADGroupMember -Identity "Okta-Users"
# Import, verify group assignment, and test SAML sign-in again.
A useful failure became a validation point.Re-enabling AD alone left the matching Okta user inactive. The import assignment failed until it was confirmed with auto-activation enabled. Restoration was successful, but this reactivation step was administrator-confirmed.
06 / Captured evidence

Authentication and authorization are separate controls.

These screenshots were supplied in the original lab conversation and show the resulting states. Personal mailbox addresses and internal identifiers have been removed. John Doe is a synthetic test identity.

GROUP-DERIVED APPLICATION ASSIGNMENT
Restored John Doe application assignment through the Okta group
The restored application assignment was group-derived. This links the final access result to the AD-managed group.
ENTITLEMENT REMOVED
Empty Okta app launcher after AD group membership removal
The user could still sign in, but no longer received the SAML application through the AD group.
IDENTITY DEACTIVATED
John Doe shown as Deactivated in Okta with personal email redacted
After disabling the AD account and importing the change, Okta displayed Deactivated.
AD ACCOUNT RE-ENABLED
Original chat evidence: AD reports Enabled = True after reactivation.
Original chat evidence: AD reports Enabled = True after reactivation.
INACTIVE IMPORT MATCH
Original chat evidence: assignment fails because the matching Okta identity is inactive. The internal user identifier is redacted.
Original chat evidence: assignment fails because the matching Okta identity is inactive. The internal user identifier is redacted.
GROUP MEMBERSHIP RESTORED
Original chat evidence: Okta-Users has one person and one assigned application after the restoration import.
Original chat evidence: Okta-Users has one person and one assigned application after the restoration import.
ACCESS RESTORED

The final login completed the journey.

Group membership was restored, the application was reassigned through the group, and the RSA demo service accepted the SAML login.

The returned NameID was jdoe@ad.phylaxcyber.com. This is the lab login identity, not the private mailbox used for email verification.

View the full evidence and commands →
RSA demo service confirms successful federation for John Doe and the lab NameID
Successful SAML federation after account reactivation and entitlement restoration.
07 / Validation boundaries

Clear outcomes. Clear limits.

CapabilityWhat this lab established
Directory integrationAD DS/DNS, agent registration, user/group import and the email attribute update were reported successful in the lab record.
AuthenticationAD delegated authentication and email verification completed. Email verification is not phishing-resistant.
AuthorizationAD group membership controlled application assignment. Removing membership removed the app tile after import.
Identity lifecycleAD disablement led to Okta deactivation. Reactivation required import confirmation with auto-activation in this run.
FederationThe RSA demo accepted SAML login after restoration. Existing service-provider session termination was not tested.

The PDF distinguishes directly captured screenshots from reported outcomes. Earlier setup images were unavailable in the conversation export; they are not presented as recreated evidence.

Production improvements outside this lab

Use redundant domain controllers in private subnets, separate agent hosts, controlled egress and phishing-resistant authentication. Test offboarding against active application sessions, monitor imports and verify failure recovery. None of these extensions is claimed as completed.

Costs and cleanup

The single server must run for imports and delegated authentication. Stopping it reduces compute usage, while EBS and retained Elastic IP costs can continue. Review credits, Windows EC2 pricing and retained resources. Rotate credentials exposed during lab troubleshooting, retire the integration safely and release unneeded infrastructure. AWS teardown was completed by the project owner after publication. This is owner-reported completion; no teardown screenshot or residual-cost audit is included. Public DNS records were retained for the GitHub-hosted portfolio.

The complete case study

Follow the build, commands and evidence.

A 14-page, public portfolio edition with the architecture, AD setup, Okta integration, lifecycle tests, security caveats, costs, cleanup and vendor references.

More Phylax Cyber projects

AWS Cloud Security Engineering

Explore the companion cloud security project: layered web protection, detection and scoped automated remediation.

Explore the cloud security project ↗