diff --git a/lib/http.go b/lib/http.go
index 6865089..67ced9f 100644
--- a/lib/http.go
+++ b/lib/http.go
@@ -20,6 +20,7 @@ package lib
 import (
 	"bytes"
 	"context"
+	"encoding/base64"
 	"fmt"
 	"io"
 	"net/http"
@@ -42,7 +43,12 @@ import (
 // the Go http.Request and http.Response structs. The client and limit parameters
 // will be used for the requests and API rate limiting. If client is nil
 // the http.DefaultClient will be used and if limit is nil an non-limiting
-// rate.Limiter will be used.
+// rate.Limiter will be used. If auth is not nil, the Authorization header
+// is populated for Basic Authentication in requests constructed for direct
+// HEAD, GET and POST method calls. Explicitly constructed requests used in
+// do_request are not affected by auth. In cases where Basic Authentication
+// is needed for these constructed requests, the basic_authentication method
+// can be used to add the necessary header.
 //
 // HEAD
 //
@@ -68,9 +74,9 @@ import (
 //
 // GET Request
 //
-// get returns a GET method request:
+// get_request returns a GET method request:
 //
-//     get(<string>) -> <map<string,dyn>>
+//     get_request(<string>) -> <map<string,dyn>>
 //
 // Example:
 //
@@ -112,7 +118,7 @@ import (
 //
 // Example:
 //
-//     post("http://www.example.com/", "text/plain", "test")
+//     post_request("http://www.example.com/", "text/plain", "test")
 //
 //     will return:
 //
@@ -144,7 +150,7 @@ import (
 // Example:
 //
 //     request("GET", "http://www.example.com/").with({"Header":{
-//         "Authorization": "Basic "+string(base64("username:password")),
+//         "Authorization": ["Basic "+string(base64("username:password"))],
 //     }})
 //
 //     will return:
@@ -153,7 +159,39 @@ import (
 //         "Close": false,
 //         "ContentLength": 0,
 //         "Header": {
-//             "Authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+//             "Authorization": [
+//                 "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+//             ]
+//         },
+//         "Host": "www.example.com",
+//         "Method": "GET",
+//         "Proto": "HTTP/1.1",
+//         "ProtoMajor": 1,
+//         "ProtoMinor": 1,
+//         "URL": "http://www.example.com/"
+//     }
+//
+//
+// Basic Authentication
+//
+// basic_authentication adds a Basic Authentication Authorization header to a request,
+// returning the modified request.
+//
+//     <map<string,dyn>>.basic_authentication(<string>, <string>) -> <map<string,dyn>>
+//
+// Example:
+//
+//     request("GET", "http://www.example.com/").basic_authentication("username", "password")
+//
+//     will return:
+//
+//     {
+//         "Close": false,
+//         "ContentLength": 0,
+//         "Header": {
+//             "Authorization": [
+//                 "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+//             ]
 //         },
 //         "Host": "www.example.com",
 //         "Method": "GET",
@@ -250,13 +288,13 @@ import (
 //
 //     line=25&page=2"
 //
-func HTTP(client *http.Client, limit *rate.Limiter) cel.EnvOption {
-	return HTTPWithContext(context.Background(), client, limit)
+func HTTP(client *http.Client, limit *rate.Limiter, auth *BasicAuth) cel.EnvOption {
+	return HTTPWithContext(context.Background(), client, limit, auth)
 }
 
-// HTTP returns a cel.EnvOption to configure extended functions for HTTP
-// requests that include a context.Context in network requests.
-func HTTPWithContext(ctx context.Context, client *http.Client, limit *rate.Limiter) cel.EnvOption {
+// HTTPWithContext returns a cel.EnvOption to configure extended functions
+// for HTTP requests that include a context.Context in network requests.
+func HTTPWithContext(ctx context.Context, client *http.Client, limit *rate.Limiter, auth *BasicAuth) cel.EnvOption {
 	if client == nil {
 		client = http.DefaultClient
 	}
@@ -266,6 +304,7 @@ func HTTPWithContext(ctx context.Context, client *http.Client, limit *rate.Limit
 	return cel.Lib(httpLib{
 		client: client,
 		limit:  limit,
+		auth:   auth,
 		ctx:    ctx,
 	})
 }
@@ -273,9 +312,17 @@ func HTTPWithContext(ctx context.Context, client *http.Client, limit *rate.Limit
 type httpLib struct {
 	client *http.Client
 	limit  *rate.Limiter
+	auth   *BasicAuth
 	ctx    context.Context
 }
 
+// BasicAuth is used to populate the Authorization header to use HTTP
+// Basic Authentication with the provided username and password for
+// direct HTTP method calls.
+type BasicAuth struct {
+	Username, Password string
+}
+
 func (httpLib) CompileOptions() []cel.EnvOption {
 	return []cel.EnvOption{
 		cel.Declarations(
@@ -341,6 +388,13 @@ func (httpLib) CompileOptions() []cel.EnvOption {
 					decls.NewMapType(decls.String, decls.Dyn),
 				),
 			),
+			decls.NewFunction("basic_authentication",
+				decls.NewInstanceOverload(
+					"map_basic_authentication_string_string",
+					[]*expr.Type{decls.NewMapType(decls.String, decls.Dyn), decls.String, decls.String},
+					decls.NewMapType(decls.String, decls.Dyn),
+				),
+			),
 			decls.NewFunction("do_request",
 				decls.NewInstanceOverload(
 					"map_do_request",
@@ -434,6 +488,12 @@ func (l httpLib) ProgramOptions() []cel.ProgramOption {
 				Function: newRequestBody,
 			},
 		),
+		cel.Functions(
+			&functions.Overload{
+				Operator: "map_basic_authentication_string_string",
+				Function: l.basicAuthentication,
+			},
+		),
 		cel.Functions(
 			&functions.Overload{
 				Operator: "map_do_request",
@@ -492,6 +552,9 @@ func (l httpLib) head(url types.String) (*http.Response, error) {
 	if err != nil {
 		return nil, err
 	}
+	if l.auth != nil {
+		req.SetBasicAuth(l.auth.Username, l.auth.Password)
+	}
 	return l.client.Do(req)
 }
 
@@ -520,6 +583,9 @@ func (l httpLib) get(url types.String) (*http.Response, error) {
 	if err != nil {
 		return nil, err
 	}
+	if l.auth != nil {
+		req.SetBasicAuth(l.auth.Username, l.auth.Password)
+	}
 	return l.client.Do(req)
 }
 
@@ -572,6 +638,9 @@ func (l httpLib) post(url, content types.String, body io.Reader) (*http.Response
 	if err != nil {
 		return nil, err
 	}
+	if l.auth != nil {
+		req.SetBasicAuth(l.auth.Username, l.auth.Password)
+	}
 	req.Header.Set("Content-Type", string(content))
 	return l.client.Do(req)
 }
@@ -722,6 +791,49 @@ func respToMap(resp *http.Response) (map[string]interface{}, error) {
 	return rm, nil
 }
 
+func (l httpLib) basicAuthentication(args ...ref.Val) ref.Val {
+	if len(args) != 3 {
+		return types.NewErr("no such overload for request")
+	}
+	request, ok := args[0].(traits.Mapper)
+	if !ok {
+		return types.ValOrErr(request, "no such overload for do_request")
+	}
+	username, ok := args[1].(types.String)
+	if !ok {
+		return types.ValOrErr(username, "no such overload for request")
+	}
+	password, ok := args[2].(types.String)
+	if !ok {
+		return types.ValOrErr(password, "no such overload for request")
+	}
+	reqm, err := request.ConvertToNative(reflectMapStringAnyType)
+	if err != nil {
+		return types.NewErr("%s", err)
+	}
+
+	// Rather than round-tripping though an http.Request, just
+	// add the Authorization header into the map directly.
+	// This reduces work required in the general case, and greatly
+	// simplifies the case where a body has already been added
+	// to the request.
+	req := reqm.(map[string]interface{})
+	var header http.Header
+	switch h := req["Header"].(type) {
+	case nil:
+		header = make(http.Header)
+		req["Header"] = header
+	case map[string][]string:
+		header = h
+	case http.Header:
+		header = h
+	default:
+		return types.NewErr("invalid type in header field: %T", h)
+	}
+	header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password)))
+	return types.DefaultTypeAdapter.NativeToValue(req)
+}
+
 func (l httpLib) doRequest(arg ref.Val) ref.Val {
 	request, ok := arg.(traits.Mapper)
 	if !ok {
diff --git a/mito.go b/mito.go
index b2187bf..d89e44a 100644
--- a/mito.go
+++ b/mito.go
@@ -148,7 +148,7 @@ var (
 		"try":         lib.Try(),
 		"file":        lib.File(mimetypes),
 		"mime":        lib.MIME(mimetypes),
-		"http":        lib.HTTP(nil, nil),
+		"http":        lib.HTTP(nil, nil, nil),
 		"limit":       lib.Limit(limitPolicies),
 	}
 
diff --git a/testdata/basic_auth.txt b/testdata/basic_auth.txt
new file mode 100644
index 0000000..cfee57b
--- /dev/null
+++ b/testdata/basic_auth.txt
@@ -0,0 +1,22 @@
+mito -use http src.cel
+! stderr .
+cmp stdout want.txt
+
+-- src.cel --
+request("GET", "http://www.example.com/").basic_authentication("username", "password")
+-- want.txt --
+{
+	"Close": false,
+	"ContentLength": 0,
+	"Header": {
+		"Authorization": [
+			"Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+		]
+	},
+	"Host": "www.example.com",
+	"Method": "GET",
+	"Proto": "HTTP/1.1",
+	"ProtoMajor": 1,
+	"ProtoMinor": 1,
+	"URL": "http://www.example.com/"
+}
diff --git a/testdata/request.txt b/testdata/request.txt
index c18b926..fe1cc62 100644
--- a/testdata/request.txt
+++ b/testdata/request.txt
@@ -7,7 +7,7 @@ cmp stdout want.txt
 	request("GET", "http://www.example.com/"),
 	request("GET", "http://www.example.com/", "request data"),
 	request("GET", "http://www.example.com/").with({"Header":{
-		"Authorization": "Basic "+string(base64("username:password")),
+		"Authorization": ["Basic "+string(base64("username:password"))],
 	}}),
 	get_request("http://www.example.com/"),
 	post_request("http://www.example.com/", "text/plain", "request data"),
@@ -41,7 +41,9 @@ cmp stdout want.txt
 		"Close": false,
 		"ContentLength": 0,
 		"Header": {
-			"Authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+			"Authorization": [
+				"Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+			]
 		},
 		"Host": "www.example.com",
 		"Method": "GET",