Overview
Many applications require two-factor authentication (2FA). Nen supports automating 2FA flows using TOTP codes (authenticator apps) and other strategies.
TOTP / Authenticator Apps
For applications using time-based one-time passwords (Google Authenticator, Authy, etc.):
Store the TOTP Secret
When setting up 2FA on the target application, save the TOTP secret key (not the QR code) as a Nen secure param:
- Look for “Can’t scan the QR code?” or “Manual entry”
- Copy the secret key (e.g.,
JBSWY3DPEHPK3PXP)
- Pass it into your workflow via
SecureParams
Generate Codes in Your Workflow
Use the pyotp library to generate codes:
import pyotp
from nen import Agent, Computer, Secure
from pydantic import BaseModel, Field
class Params(BaseModel):
...
class SecureParams(BaseModel):
totp_secret: Secure[str]
class Result(BaseModel):
success: bool
def run(params: Params, secure_params: SecureParams) -> Result:
agent = Agent()
computer = Computer()
# Login steps...
agent.execute("Enter username and password")
if not agent.verify("Is the 2FA prompt visible?"):
raise RuntimeError("2FA prompt did not appear")
# Generate TOTP code
# Note: totp_secret must be the plain string value for pyotp.
# Use a Params field (not SecureParams) if you need to pass it to pyotp directly,
# or handle TOTP generation in a pre-processing step outside the sandbox.
totp = pyotp.TOTP(params.totp_secret_plain)
code = totp.now()
# Enter the code
agent.execute("Click the 2FA code input field")
computer.type(code, interval=0.05)
computer.press("Return")
return Result(success=agent.verify("Is the dashboard visible?", timeout=15))
TOTP codes refresh every 30 seconds. The code is valid for the current 30-second window plus typically one window before and after.
Since SecureValue references can only be passed to computer.type(), TOTP secrets that need to be passed to external libraries (like pyotp) should be included as a plain Params field rather than SecureParams, or generated outside the workflow and passed as an already-computed code via Params.
Email Codes
For applications that send codes via email:
Email Access
If you have API access to the email inbox:
import requests
import time
from nen import Agent, Computer
from pydantic import BaseModel, Field
class Params(BaseModel):
...
class SecureParams(BaseModel):
email_api_key: Secure[str]
class Result(BaseModel):
success: bool
def run(params: Params, secure_params: SecureParams) -> Result:
agent = Agent()
computer = Computer()
# Trigger 2FA code to be sent
agent.execute("Click 'Send verification code'")
# Wait for email and fetch code from your email API
time.sleep(5)
response = requests.get(
"https://your-email-api.com/latest",
headers={"Authorization": f"Bearer {params.email_api_token}"}
)
code = extract_code_from_email(response.json())
# Enter the code
agent.execute("Click the verification code field")
computer.type(code)
return Result(success=agent.verify("Is the dashboard visible?", timeout=15))