How to Create a User in Oracle - Grants & Privileges
How to Create a User in Oracle
Section titled “How to Create a User in Oracle”Creating a user in Oracle involves more than just CREATE USER — you need to assign a default tablespace, set a quota, grant the right privileges, and attach a profile for password and resource management. This guide covers every step for a production-ready user.
Prerequisites
Section titled “Prerequisites”You need the CREATE USER system privilege (typically held by DBAs). For multi-tenant databases (CDB/PDB), decide whether you’re creating a common user (C## prefix, exists in all containers) or a local user (PDB-only).
-- Check your current privilegesSELECT privilege FROM session_privs WHERE privilege = 'CREATE USER';
-- If working in a CDB, check which container you're inSHOW CON_NAME;
-- For PDB work, connect to the right PDBALTER SESSION SET CONTAINER = pdb_prod;Step 1: Create a Basic Application User
Section titled “Step 1: Create a Basic Application User”-- Create a standard application userCREATE USER app_user IDENTIFIED BY "SecureP@ssw0rd2024" DEFAULT TABLESPACE app_data TEMPORARY TABLESPACE temp QUOTA 10G ON app_data ACCOUNT UNLOCK;
-- Grant CREATE SESSION so the user can log inGRANT CREATE SESSION TO app_user;Without GRANT CREATE SESSION, the user will receive ORA-01045 when trying to connect.
Step 2: Grant Standard Roles
Section titled “Step 2: Grant Standard Roles”Oracle provides predefined roles that bundle common privileges.
-- For a developer/application schema ownerGRANT CONNECT, RESOURCE TO app_user;
-- RESOURCE includes: CREATE TABLE, CREATE INDEX, CREATE PROCEDURE,-- CREATE SEQUENCE, CREATE TRIGGER, CREATE TYPE, CREATE CLUSTER
-- For a read-only reporting userGRANT CREATE SESSION TO report_user;GRANT SELECT ANY TABLE TO report_user; -- Broad — prefer object-level grants
-- For a DBA user (admin work only, not application connections)GRANT DBA TO dba_app_user;Step 3: Grant Object-Level Privileges
Section titled “Step 3: Grant Object-Level Privileges”Prefer explicit object grants over broad system privileges — this follows the principle of least privilege.
-- Grant SELECT on specific tables to a reporting userGRANT SELECT ON app_schema.orders TO report_user;GRANT SELECT ON app_schema.customers TO report_user;GRANT SELECT ON app_schema.products TO report_user;
-- Grant DML permissions for an application userGRANT SELECT, INSERT, UPDATE, DELETE ON app_schema.orders TO app_user;GRANT SELECT, INSERT ON app_schema.audit_log TO app_user;
-- Grant EXECUTE on packages and proceduresGRANT EXECUTE ON app_schema.order_pkg TO app_user;GRANT EXECUTE ON app_schema.util_pkg TO app_user;
-- Allow the user to grant their own privileges to others (with GRANT OPTION)GRANT SELECT ON app_schema.reference_data TO report_user WITH GRANT OPTION;Step 4: Set Tablespace Quotas
Section titled “Step 4: Set Tablespace Quotas”Without a quota, a user with RESOURCE role or UNLIMITED TABLESPACE will consume space without limits.
-- Set a specific quotaALTER USER app_user QUOTA 20G ON app_data;ALTER USER app_user QUOTA 2G ON app_idx;
-- Remove quota restriction (unlimited on a specific tablespace)ALTER USER app_user QUOTA UNLIMITED ON app_data;
-- Check current quotasSELECT username, tablespace_name, ROUND(bytes/1024/1024, 0) AS used_mb, DECODE(max_bytes, -1, 'UNLIMITED', ROUND(max_bytes/1024/1024, 0)) AS quota_mbFROM dba_ts_quotasWHERE username = 'APP_USER';Note: GRANT RESOURCE in Oracle 12c+ no longer implicitly grants UNLIMITED TABLESPACE. You must set quotas explicitly.
Step 5: Assign a Profile
Section titled “Step 5: Assign a Profile”Profiles enforce password policies and resource limits.
-- Create a profile for application usersCREATE PROFILE app_profile LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1/24 -- 1 hour PASSWORD_LIFE_TIME 180 -- 180 days PASSWORD_REUSE_TIME 365 PASSWORD_REUSE_MAX 10 PASSWORD_GRACE_TIME 7 PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function SESSIONS_PER_USER UNLIMITED CPU_PER_SESSION UNLIMITED CONNECT_TIME UNLIMITED IDLE_TIME 60; -- Disconnect after 60 min idle
-- Assign profile to userALTER USER app_user PROFILE app_profile;
-- Verify profile assignmentSELECT username, profile, account_status, expiry_dateFROM dba_usersWHERE username = 'APP_USER';Step 6: Create a Schema-Only Account (Oracle 18c+)
Section titled “Step 6: Create a Schema-Only Account (Oracle 18c+)”Schema-only accounts have no password and cannot log in directly — they just own objects. Applications connect as a different user and reference the schema.
-- Create schema-only account (no password, no login)CREATE USER app_schema NO AUTHENTICATION DEFAULT TABLESPACE app_data QUOTA UNLIMITED ON app_data;
-- Create the connecting application userCREATE USER app_connect IDENTIFIED BY "ConnectP@ss2024" DEFAULT TABLESPACE app_data TEMPORARY TABLESPACE temp;
GRANT CREATE SESSION TO app_connect;
-- Grant app_connect access to app_schema objectsGRANT SELECT, INSERT, UPDATE, DELETE ON app_schema.orders TO app_connect;Advanced Examples
Section titled “Advanced Examples”Create a Common User in a CDB
Section titled “Create a Common User in a CDB”-- Must be connected as a common user with CREATE USER privilege-- Common users must start with C##CREATE USER c##dba_monitor IDENTIFIED BY "MonitorP@ss2024" CONTAINER = ALL;
GRANT SET CONTAINER TO c##dba_monitor CONTAINER=ALL;GRANT CREATE SESSION TO c##dba_monitor CONTAINER=ALL;GRANT SELECT ANY DICTIONARY TO c##dba_monitor CONTAINER=ALL;Create a Proxy User
Section titled “Create a Proxy User”Proxy authentication lets one user connect on behalf of another — useful for connection pools.
-- Allow app_pool to proxy for app_userALTER USER app_user GRANT CONNECT THROUGH app_pool;
-- Application connects as: app_pool[app_user]-- Verify proxy configurationSELECT proxy, client, authentication, flagsFROM proxy_usersWHERE client = 'APP_USER';Common Mistakes and Pitfalls
Section titled “Common Mistakes and Pitfalls”No DEFAULT TABLESPACE specified — The user lands in the SYSTEM tablespace by default, and any objects they create pollute the SYSTEM tablespace.
Granting DBA to application users — GRANT DBA is far too broad for application accounts. It grants access to every object and every system privilege.
Forgetting to set a quota — A user without a quota or UNLIMITED TABLESPACE privilege gets ORA-01950 when trying to create objects.
Weak passwords — Oracle 12c+ password complexity functions are available. Use them via profiles to enforce strength requirements.
Not assigning a profile — Without a profile, DEFAULT is used, which has unlimited failed login attempts and no password expiry in some configurations.
Creating users as SYS or SYSTEM — Never create application users that connect as SYS or SYSTEM. Create a dedicated DBA account instead.
Verification Queries
Section titled “Verification Queries”-- Confirm user was created correctlySELECT username, account_status, default_tablespace, temporary_tablespace, profile, created, expiry_dateFROM dba_usersWHERE username = 'APP_USER';
-- Check all granted system privilegesSELECT grantee, privilege, admin_optionFROM dba_sys_privsWHERE grantee = 'APP_USER'ORDER BY privilege;
-- Check all granted rolesSELECT grantee, granted_role, admin_option, default_roleFROM dba_role_privsWHERE grantee = 'APP_USER'ORDER BY granted_role;
-- Check tablespace quotasSELECT tablespace_name, ROUND(bytes/1024/1024, 0) AS used_mb, DECODE(max_bytes, -1, 'UNLIMITED', ROUND(max_bytes/1024/1024, 0)) AS limit_mbFROM dba_ts_quotasWHERE username = 'APP_USER';
-- Check object-level grants the user has receivedSELECT owner, table_name, privilege, grantableFROM dba_tab_privsWHERE grantee = 'APP_USER'ORDER BY owner, table_name;Related Topics
Section titled “Related Topics”- How to Gather Statistics - After populating the schema
- Security Analysis Scripts - Audit user privileges
- Oracle Errors: ORA-01045 - Missing CREATE SESSION
- Oracle Errors: ORA-01950 - No tablespace quota